diff --git a/cmd/bundler.go b/cmd/bundler.go index 0049d64..4ea67df 100644 --- a/cmd/bundler.go +++ b/cmd/bundler.go @@ -6,6 +6,7 @@ import ( parser_io "github.com/aquasecurity/go-dep-parser/pkg/io" "github.com/aquasecurity/go-dep-parser/pkg/ruby/bundler" "github.com/kyoshidajp/dep-doctor/cmd/github" + "golang.org/x/exp/slices" ) type BundlerDoctor struct { @@ -15,7 +16,7 @@ func NewBundlerDoctor() *BundlerDoctor { return &BundlerDoctor{} } -func (b *BundlerDoctor) Diagnose(r parser_io.ReadSeekerAt, year int) map[string]Diagnosis { +func (b *BundlerDoctor) Diagnose(r parser_io.ReadSeekerAt, year int, ignores []string) map[string]Diagnosis { diagnoses := make(map[string]Diagnosis) slicedNameWithOwners := [][]github.NameWithOwner{} nameWithOwners := b.NameWithOwners(r) @@ -32,10 +33,12 @@ func (b *BundlerDoctor) Diagnose(r parser_io.ReadSeekerAt, year int) map[string] for _, nameWithOwners := range slicedNameWithOwners { repos := github.FetchFromGitHub(nameWithOwners) for _, r := range repos { + isIgnore := slices.Contains(ignores, r.Name) diagnosis := Diagnosis{ Name: r.Name, Url: r.Url, Archived: r.Archived, + Ignored: isIgnore, Diagnosed: true, IsActive: r.IsActive(year), } diff --git a/cmd/diagnose.go b/cmd/diagnose.go index 683f807..d9c19d9 100644 --- a/cmd/diagnose.go +++ b/cmd/diagnose.go @@ -18,7 +18,7 @@ import ( const MAX_YEAR_TO_BE_BLANK = 5 type Doctor interface { - Diagnose(r io.ReadSeekerAt, year int) map[string]Diagnosis + Diagnose(r io.ReadSeekerAt, year int, ignores []string) map[string]Diagnosis NameWithOwners(r parser_io.ReadSeekerAt) []github.NameWithOwner } @@ -26,6 +26,7 @@ type Diagnosis struct { Name string Url string Archived bool + Ignored bool Diagnosed bool IsActive bool } @@ -40,13 +41,18 @@ func NewDepartment(d Doctor) *Department { } } -func (d *Department) Diagnose(r io.ReadSeekCloserAt, year int) map[string]Diagnosis { - return d.doctor.Diagnose(r, year) +func (d *Department) Diagnose(r io.ReadSeekCloserAt, year int, ignores []string) map[string]Diagnosis { + return d.doctor.Diagnose(r, year, ignores) } type Options struct { packageManager string lockFilePath string + ignores string +} + +func (o *Options) Ignores() []string { + return strings.Split(o.ignores, " ") } var ( @@ -85,7 +91,7 @@ var diagnoseCmd = &cobra.Command{ } department := NewDepartment(doctor) - diagnoses := department.Diagnose(f, MAX_YEAR_TO_BE_BLANK) + diagnoses := department.Diagnose(f, MAX_YEAR_TO_BE_BLANK, o.Ignores()) if err := Report(diagnoses); err != nil { os.Exit(1) } @@ -96,14 +102,23 @@ func init() { rootCmd.AddCommand(diagnoseCmd) diagnoseCmd.Flags().StringVarP(&o.packageManager, "package", "p", "bundler", "package manager") diagnoseCmd.Flags().StringVarP(&o.lockFilePath, "lock_file", "f", "Gemfile.lock", "lock file path") + diagnoseCmd.Flags().StringVarP(&o.ignores, "ignores", "i", "", "ignore dependencies") } func Report(diagnoses map[string]Diagnosis) error { errMessages := []string{} warnMessages := []string{} + ignoredMessages := []string{} errCount := 0 unDiagnosedCount := 0 + ignoredCount := 0 for _, diagnosis := range diagnoses { + if diagnosis.Ignored { + ignoredMessages = append(ignoredMessages, fmt.Sprintf("[info] %s (ignored):", diagnosis.Name)) + ignoredCount += 1 + continue + } + if !diagnosis.Diagnosed { warnMessages = append(warnMessages, fmt.Sprintf("[warn] %s (unknown):", diagnosis.Name)) unDiagnosedCount += 1 @@ -120,6 +135,9 @@ func Report(diagnoses map[string]Diagnosis) error { } fmt.Printf("\n") + if len(ignoredMessages) > 0 { + fmt.Println(strings.Join(ignoredMessages, "\n")) + } if len(warnMessages) > 0 { color.Yellow(strings.Join(warnMessages, "\n")) } @@ -129,10 +147,11 @@ func Report(diagnoses map[string]Diagnosis) error { color.Green(heredoc.Docf(` Diagnose complete! %d dependencies. - %d error, %d unknown`, + %d error, %d unknown, %d ignored`, len(diagnoses), errCount, - unDiagnosedCount), + unDiagnosedCount, + ignoredCount), ) if len(errMessages) > 0 { diff --git a/cmd/diagnose_test.go b/cmd/diagnose_test.go index 7c72e65..8e907a1 100644 --- a/cmd/diagnose_test.go +++ b/cmd/diagnose_test.go @@ -14,6 +14,7 @@ func TestDiagnose(t *testing.T) { Name: "faker", Url: "https://github.com/faker-ruby/faker", Archived: false, + Ignored: false, Diagnosed: true, IsActive: true, }, @@ -21,6 +22,7 @@ func TestDiagnose(t *testing.T) { Name: "concurrent-ruby", Url: "https://github.com/ruby-concurrency/concurrent-ruby", Archived: false, + Ignored: false, Diagnosed: true, IsActive: true, }, @@ -28,6 +30,7 @@ func TestDiagnose(t *testing.T) { Name: "i18n", Url: "https://github.com/ruby-i18n/i18n", Archived: false, + Ignored: true, Diagnosed: true, IsActive: true, }, @@ -35,6 +38,7 @@ func TestDiagnose(t *testing.T) { Name: "method_source", Url: "https://github.com/banister/method_source", Archived: false, + Ignored: false, Diagnosed: true, IsActive: true, }, @@ -42,6 +46,7 @@ func TestDiagnose(t *testing.T) { Name: "paperclip", Url: "https://github.com/thoughtbot/paperclip", Archived: true, + Ignored: false, Diagnosed: true, IsActive: false, }, @@ -49,6 +54,7 @@ func TestDiagnose(t *testing.T) { Name: "dotenv", Url: "https://github.com/bkeepers/dotenv", Archived: false, + Ignored: false, Diagnosed: true, IsActive: true, }, @@ -60,7 +66,8 @@ func TestDiagnose(t *testing.T) { defer f.Close() doctor := NewDepartment(NewBundlerDoctor()) - diagnoses := doctor.Diagnose(f, 2) + ignores := []string{"i18n"} + diagnoses := doctor.Diagnose(f, 2, ignores) assert.Equal(t, expect, diagnoses) }) } diff --git a/cmd/npm.go b/cmd/npm.go index 5a6f384..3316f42 100644 --- a/cmd/npm.go +++ b/cmd/npm.go @@ -15,7 +15,7 @@ func NewNPMDoctor() *NPMDoctor { return &NPMDoctor{} } -func (d *NPMDoctor) Diagnose(r parser_io.ReadSeekerAt, year int) map[string]Diagnosis { +func (d *NPMDoctor) Diagnose(r parser_io.ReadSeekerAt, year int, ignores []string) map[string]Diagnosis { diagnoses := make(map[string]Diagnosis) slicedNameWithOwners := [][]github.NameWithOwner{} nameWithOwners := d.NameWithOwners(r) diff --git a/cmd/pip.go b/cmd/pip.go index e80ff96..8124dc0 100644 --- a/cmd/pip.go +++ b/cmd/pip.go @@ -15,7 +15,7 @@ func NewPipDoctor() *PipDoctor { return &PipDoctor{} } -func (d *PipDoctor) Diagnose(r parser_io.ReadSeekerAt, year int) map[string]Diagnosis { +func (d *PipDoctor) Diagnose(r parser_io.ReadSeekerAt, year int, ignores []string) map[string]Diagnosis { diagnoses := make(map[string]Diagnosis) slicedNameWithOwners := [][]github.NameWithOwner{} nameWithOwners := d.NameWithOwners(r) diff --git a/cmd/yarn.go b/cmd/yarn.go index d2f9caa..a04021a 100644 --- a/cmd/yarn.go +++ b/cmd/yarn.go @@ -15,7 +15,7 @@ func NewYarnDoctor() *YarnDoctor { return &YarnDoctor{} } -func (d *YarnDoctor) Diagnose(r parser_io.ReadSeekerAt, year int) map[string]Diagnosis { +func (d *YarnDoctor) Diagnose(r parser_io.ReadSeekerAt, year int, ignores []string) map[string]Diagnosis { diagnoses := make(map[string]Diagnosis) slicedNameWithOwners := [][]github.NameWithOwner{} nameWithOwners := d.NameWithOwners(r)