diff --git a/api/v1alpha1/gitrepository_types.go b/api/v1alpha1/gitrepository_types.go index aa15bd9d..ac05b048 100644 --- a/api/v1alpha1/gitrepository_types.go +++ b/api/v1alpha1/gitrepository_types.go @@ -54,6 +54,13 @@ type GitRepositorySpec struct { // Verify OpenPGP signature for the commit that HEAD points to. // +optional Verification *GitRepositoryVerification `json:"verify,omitempty"` + + // SourceIgnore overrides the set of excluded patterns in the .sourceignore + // format (which is the same as .gitignore). If not provided, a default will + // be used, consult the documentation for your version to find out what those + // are. + // +optional + SourceIgnore *string `json:"sourceIgnore,omitempty"` } // GitRepositoryRef defines the git ref used for pull and checkout operations. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index f97d00a3..dc1f2393 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -140,6 +140,11 @@ func (in *GitRepositorySpec) DeepCopyInto(out *GitRepositorySpec) { *out = new(GitRepositoryVerification) **out = **in } + if in.SourceIgnore != nil { + in, out := &in.SourceIgnore, &out.SourceIgnore + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GitRepositorySpec. diff --git a/config/crd/bases/source.fluxcd.io_gitrepositories.yaml b/config/crd/bases/source.fluxcd.io_gitrepositories.yaml index 04954473..fb4fc258 100644 --- a/config/crd/bases/source.fluxcd.io_gitrepositories.yaml +++ b/config/crd/bases/source.fluxcd.io_gitrepositories.yaml @@ -82,6 +82,12 @@ spec: TODO: Add other useful fields. apiVersion, kind, uid?' type: string type: object + sourceIgnore: + description: SourceIgnore overrides the set of excluded patterns in + the .sourceignore format (which is the same as .gitignore). If not + provided, a default will be used, consult the documentation for your + version to find out what those are. + type: string timeout: description: The timeout for remote git operations like cloning, default to 20s. diff --git a/controllers/gitrepository_controller.go b/controllers/gitrepository_controller.go index cb5c4761..b904cd01 100644 --- a/controllers/gitrepository_controller.go +++ b/controllers/gitrepository_controller.go @@ -198,8 +198,7 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1. defer unlock() // archive artifact and check integrity - err = r.Storage.Archive(artifact, tmpGit) - if err != nil { + if err := r.Storage.Archive(artifact, tmpGit, repository.Spec); err != nil { err = fmt.Errorf("storage archive error: %w", err) return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } diff --git a/controllers/storage.go b/controllers/storage.go index 7838ecd7..599a8d1f 100644 --- a/controllers/storage.go +++ b/controllers/storage.go @@ -19,6 +19,7 @@ package controllers import ( "archive/tar" "bufio" + "bytes" "compress/gzip" "crypto/sha1" "fmt" @@ -108,7 +109,7 @@ func (s *Storage) RemoveAllButCurrent(artifact sourcev1.Artifact) error { }) if len(errors) > 0 { - return fmt.Errorf("faild to remove files: %s", strings.Join(errors, " ")) + return fmt.Errorf("failed to remove files: %s", strings.Join(errors, " ")) } return nil } @@ -123,15 +124,17 @@ func (s *Storage) ArtifactExist(artifact sourcev1.Artifact) bool { // Archive creates a tar.gz to the artifact path from the given dir excluding any VCS specific // files and directories, or any of the excludes defined in the excludeFiles. -func (s *Storage) Archive(artifact sourcev1.Artifact, dir string) error { +// Returns a modified sourcev1.Artifact and any error. +func (s *Storage) Archive(artifact sourcev1.Artifact, dir string, spec sourcev1.GitRepositorySpec) error { if _, err := os.Stat(dir); err != nil { return err } - ps, err := loadExcludePatterns(dir) + ps, err := loadExcludePatterns(dir, spec) if err != nil { return err } + matcher := gitignore.NewMatcher(ps) gzFile, err := os.Create(artifact.Path) @@ -241,27 +244,44 @@ func (s *Storage) Lock(artifact sourcev1.Artifact) (unlock func(), err error) { return mutex.Lock() } -func loadExcludePatterns(dir string) ([]gitignore.Pattern, error) { +func getPatterns(reader io.Reader, path []string) []gitignore.Pattern { + ps := []gitignore.Pattern{} + scanner := bufio.NewScanner(reader) + + for scanner.Scan() { + s := scanner.Text() + if !strings.HasPrefix(s, "#") && len(strings.TrimSpace(s)) > 0 { + ps = append(ps, gitignore.ParsePattern(s, path)) + } + } + + return ps +} + +// loadExcludePatterns loads the excluded patterns from sourceignore or other +// sources. +func loadExcludePatterns(dir string, spec sourcev1.GitRepositorySpec) ([]gitignore.Pattern, error) { path := strings.Split(dir, "/") + var ps []gitignore.Pattern for _, p := range strings.Split(excludeVCS, ",") { ps = append(ps, gitignore.ParsePattern(p, path)) } - for _, p := range strings.Split(excludeExt, ",") { - ps = append(ps, gitignore.ParsePattern(p, path)) - } - if f, err := os.Open(filepath.Join(dir, excludeFile)); err == nil { - defer f.Close() - scanner := bufio.NewScanner(f) - for scanner.Scan() { - s := scanner.Text() - if !strings.HasPrefix(s, "#") && len(strings.TrimSpace(s)) > 0 { - ps = append(ps, gitignore.ParsePattern(s, path)) - } + if spec.SourceIgnore == nil { + for _, p := range strings.Split(excludeExt, ",") { + ps = append(ps, gitignore.ParsePattern(p, path)) } - } else if !os.IsNotExist(err) { - return nil, err + + if f, err := os.Open(filepath.Join(dir, excludeFile)); err == nil { + defer f.Close() + ps = append(ps, getPatterns(f, path)...) + } else if !os.IsNotExist(err) { + return nil, err + } + } else { + ps = append(ps, getPatterns(bytes.NewBufferString(*spec.SourceIgnore), path)...) } + return ps, nil } diff --git a/docs/api/source.md b/docs/api/source.md index b80a9591..2bdf2f79 100644 --- a/docs/api/source.md +++ b/docs/api/source.md @@ -157,6 +157,21 @@ GitRepositoryVerification
Verify OpenPGP signature for the commit that HEAD points to.
+sourceIgnore
SourceIgnore overrides the set of excluded patterns in the .sourceignore +format (which is the same as .gitignore). If not provided, a default will +be used, consult the documentation for your version to find out what those +are.
+Verify OpenPGP signature for the commit that HEAD points to.
+sourceIgnore
SourceIgnore overrides the set of excluded patterns in the .sourceignore +format (which is the same as .gitignore). If not provided, a default will +be used, consult the documentation for your version to find out what those +are.
+