Skip to content

Commit

Permalink
Add pip to dbotconf
Browse files Browse the repository at this point in the history
requirements.txt files will now be tracked with dependabot.

This is related to open-telemetry/opentelemetry-go#3996.
  • Loading branch information
CharlieTLe committed May 1, 2023
1 parent fefc7ef commit a631cca
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 83 deletions.
2 changes: 2 additions & 0 deletions dbotconf/internal/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ const (
ghPkgEco = "github-actions"
dockerPkgEco = "docker"
gomodPkgEco = "gomod"
pipPkgEco = "pip"
)

var (
weeklySchedule = schedule{Interval: "weekly", Day: "sunday"}
actionLabels = []string{"dependencies", "actions", "Skip Changelog"}
dockerLabels = []string{"dependencies", "docker", "Skip Changelog"}
goLabels = []string{"dependencies", "go", "Skip Changelog"}
pipLabels = []string{"dependencies", "pip", "Skip Changelog"}
)

type dependabotConfig struct {
Expand Down
24 changes: 22 additions & 2 deletions dbotconf/internal/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const header = "# File generated by dbotconf; DO NOT EDIT."
var buildConfigFunc = buildConfig

// buildConfig constructs a dependabotConfig for all modules in the repo.
func buildConfig(root string, mods []*modfile.File, dockerFiles []string) (*dependabotConfig, error) {
func buildConfig(root string, mods []*modfile.File, dockerFiles []string, pipFiles []string) (*dependabotConfig, error) {
c := &dependabotConfig{
Version: version2,
Updates: []update{
Expand Down Expand Up @@ -70,6 +70,21 @@ func buildConfig(root string, mods []*modfile.File, dockerFiles []string) (*depe
Schedule: weeklySchedule,
})
}

for _, p := range pipFiles {
local, err := localPath(root, p)
if err != nil {
return nil, err
}

c.Updates = append(c.Updates, update{
PackageEcosystem: pipPkgEco,
Directory: local,
Labels: pipLabels,
Schedule: weeklySchedule,
})
}

return c, nil
}

Expand All @@ -88,7 +103,12 @@ func generate() error {
return err
}

c, err := buildConfigFunc(root, mods, dockerFiles)
pipFiles, err := allPipFunc(root)
if err != nil {
return err
}

c, err := buildConfigFunc(root, mods, dockerFiles, pipFiles)
if err != nil {
return err
}
Expand Down
16 changes: 13 additions & 3 deletions dbotconf/internal/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,11 @@ func TestBuildConfig(t *testing.T) {
"/home/user/repo/a/",
"/home/user/repo/b/",
}
pipFiles := []string{
"/home/user/repo/requirements.txt",
}

got, err := buildConfig(root, mods, dockerFiles)
got, err := buildConfig(root, mods, dockerFiles, pipFiles)
require.NoError(t, err)
assert.Equal(t, &dependabotConfig{
Version: version2,
Expand All @@ -82,6 +85,7 @@ func TestBuildConfig(t *testing.T) {
newUpdate(gomodPkgEco, "/", goLabels),
newUpdate(gomodPkgEco, "/a", goLabels),
newUpdate(gomodPkgEco, "/b", goLabels),
newUpdate(pipPkgEco, "/", pipLabels),
},
}, got)
}
Expand Down Expand Up @@ -119,11 +123,17 @@ func TestRunGenerateReturnBuildConfigError(t *testing.T) {
allDockerFunc = func(string) ([]string, error) {
return nil, nil
}
t.Cleanup(func(f func(string) ([]string, error)) func() {
return func() { allPipFunc = f }
}(allPipFunc))
allPipFunc = func(string) ([]string, error) {
return nil, nil
}

t.Cleanup(func(f func(string, []*modfile.File, []string) (*dependabotConfig, error)) func() {
t.Cleanup(func(f func(string, []*modfile.File, []string, []string) (*dependabotConfig, error)) func() {
return func() { buildConfigFunc = f }
}(buildConfigFunc))
buildConfigFunc = func(string, []*modfile.File, []string) (*dependabotConfig, error) {
buildConfigFunc = func(string, []*modfile.File, []string, []string) (*dependabotConfig, error) {
return nil, assert.AnError
}
assert.ErrorIs(t, generate(), assert.AnError)
Expand Down
5 changes: 5 additions & 0 deletions dbotconf/internal/mods.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
var (
allModsFunc = allMods
allDockerFunc = allDocker
allPipFunc = allPip
configuredUpdatesFunc = configuredUpdates
)

Expand All @@ -51,6 +52,10 @@ func allDocker(root string) ([]string, error) {
return repo.FindFilePatternDirs(root, "*Dockerfile*")
}

func allPip(root string) ([]string, error) {
return repo.FindFilePatternDirs(root, "*requirements.txt")
}

// localModPath returns the dependabot appropriate directory name for module
// mod that resides in a repo with root.
func localModPath(root string, mod *modfile.File) (string, error) {
Expand Down
117 changes: 63 additions & 54 deletions dbotconf/internal/testdata/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,57 +1,66 @@
# File generated by dbotconf; DO NOT EDIT.
version: 2
updates:
- package-ecosystem: github-actions
directory: /
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: docker
directory: /
labels:
- dependencies
- docker
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: docker
directory: /a/b/example
labels:
- dependencies
- docker
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /a
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /a/b
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: github-actions
directory: /
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: docker
directory: /
labels:
- dependencies
- docker
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: docker
directory: /a/b/example
labels:
- dependencies
- docker
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /a
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: gomod
directory: /a/b
labels:
- dependencies
- actions
- Skip Changelog
schedule:
interval: weekly
day: sunday
- package-ecosystem: pip
directory: /
labels:
- dependencies
- pip
- Skip Changelog
schedule:
interval: weekly
day: sunday
43 changes: 33 additions & 10 deletions dbotconf/internal/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,41 @@ var (
errNotEnoughArg = errors.New("path argument required")
)

// configuredUpdates returns the set of Go modules and Dockerfiles dependabot
// configuredUpdates returns the set of Go modules, Dockerfiles, Pip requirements dependabot
// is configured to check updates for.
func configuredUpdates(path string) (mods map[string]struct{}, docker map[string]struct{}, err error) {
func configuredUpdates(path string) (mods map[string]struct{}, docker map[string]struct{}, pip map[string]struct{}, err error) {
f, err := os.Open(filepath.Clean(path))
if errors.Is(err, os.ErrNotExist) {
return nil, nil, fmt.Errorf("dependabot configuration file does not exist: %s", path)
return nil, nil, nil, fmt.Errorf("dependabot configuration file does not exist: %s", path)
}
if err != nil {
return nil, nil, fmt.Errorf("failed to read dependabot configuration file: %s", path)
return nil, nil, nil, fmt.Errorf("failed to read dependabot configuration file: %s", path)
}

var c dependabotConfig
if err := yaml.NewDecoder(f).Decode(&c); err != nil {
return nil, nil, fmt.Errorf("invalid dependabot configuration: %w", err)
return nil, nil, nil, fmt.Errorf("invalid dependabot configuration: %w", err)
}

mods = make(map[string]struct{})
docker = make(map[string]struct{})
pip = make(map[string]struct{})
for _, u := range c.Updates {
if u.PackageEcosystem == dockerPkgEco {
docker[u.Directory] = struct{}{}
}
if u.PackageEcosystem == gomodPkgEco {
mods[u.Directory] = struct{}{}
}
if u.PackageEcosystem == pipPkgEco {
pip[u.Directory] = struct{}{}
}
}
return mods, docker, nil
return mods, docker, pip, nil
}

// verify ensures dependabot configuration contains a check for all modules and
// Dockerfiles.
// verify ensures dependabot configuration contains a check for all modules,
// Dockerfiles, and requirements.txt files.
func verify(args []string) error {
switch len(args) {
case 0:
Expand All @@ -80,7 +84,12 @@ func verify(args []string) error {
return err
}

modUp, dockerUp, err := configuredUpdatesFunc(args[0])
pipFiles, err := allPipFunc(root)
if err != nil {
return err
}

modUp, dockerUp, pipUp, err := configuredUpdatesFunc(args[0])
if err != nil {
return err
}
Expand All @@ -107,15 +116,29 @@ func verify(args []string) error {
missingDocker = append(missingDocker, local)
}
}
var missingPip []string
for _, p := range pipFiles {
local, err := localPath(root, p)
if err != nil {
return err
}

if _, ok := pipUp[local]; !ok {
missingPip = append(missingPip, local)
}
}

if len(missingMod) > 0 || len(missingDocker) > 0 {
if len(missingMod) > 0 || len(missingDocker) > 0 || len(missingPip) > 0 {
msg := "missing update check(s):"
if len(missingMod) > 0 {
msg = fmt.Sprintf("%s\n- Go mod files: %s", msg, strings.Join(missingMod, ", "))
}
if len(missingDocker) > 0 {
msg = fmt.Sprintf("%s\n- Dockerfiles: %s", msg, strings.Join(missingDocker, ", "))
}
if len(missingPip) > 0 {
msg = fmt.Sprintf("%s\n- Pip files: %s", msg, strings.Join(missingPip, ", "))
}
msg += "\n"
return errors.New(msg)
}
Expand Down
Loading

0 comments on commit a631cca

Please sign in to comment.