Skip to content

Commit

Permalink
refact: Simplify dib options about paths
Browse files Browse the repository at this point in the history
  • Loading branch information
julienvey committed Jan 14, 2022
1 parent 88d7621 commit ce6dc87
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 40 deletions.
56 changes: 50 additions & 6 deletions cmd/build.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package main

import (
"errors"
"fmt"
"os"
"path"

"github.com/radiofrance/dib/docker"
Expand Down Expand Up @@ -36,25 +39,41 @@ func cmdBuild(cmd *cli.Cmd) {

cmd.Action = func() {
preflight.RunPreflightChecks([]string{"docker"})

DAG, err := doBuild(opts)
if err != nil {
logrus.Fatalf("Build failed: %v", err)
}

if opts.generateGraph {
if err := graphviz.GenerateGraph(DAG, opts.outputDir); err != nil {
workingDir, err := getWorkingDir()
if err != nil {
logrus.Fatalf("failed to get current working directory: %v", err)
}
if err := graphviz.GenerateGraph(DAG, workingDir); err != nil {
logrus.Fatalf("Generating graph failed: %v", err)
}
}
}
}

func getWorkingDir() (string, error) {
currentDir, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("failed to get current working directory: %w", err)
}
return currentDir, nil
}

func doBuild(opts buildOpts) (*dag.DAG, error) {
workingDir, err := getWorkingDir()
if err != nil {
return nil, fmt.Errorf("failed to get current working directory: %w", err)
}
shell := &exec.ShellExecutor{
Dir: opts.inputDir,
Dir: workingDir,
}

var err error
gcrRegistry, err := registry.NewRegistry(opts.registryURL, opts.dryRun)
if err != nil {
return nil, err
Expand All @@ -74,19 +93,24 @@ func doBuild(opts buildOpts) (*dag.DAG, error) {
DAG.Tagger = gcrRegistry
}

buildPath := path.Join(opts.inputDir, opts.buildDir)
buildPath := path.Join(workingDir, opts.buildPath)
logrus.Infof("Building images in directory \"%s\"", buildPath)

logrus.Debug("Generate DAG")
DAG.GenerateDAG(buildPath, opts.registryURL)
logrus.Debug("Generate DAG -- Done")

currentVersion, err := versn.CheckDockerVersionIntegrity(opts.inputDir, opts.buildDir)
dockerDir, err := findDockerRootDir(workingDir, opts.buildPath)
if err != nil {
return nil, err
}

currentVersion, err := versn.CheckDockerVersionIntegrity(path.Join(workingDir, dockerDir))
if err != nil {
return nil, err
}

previousVersion, diffs, err := versn.GetDiffSinceLastDockerVersionChange(opts.inputDir, shell)
previousVersion, diffs, err := versn.GetDiffSinceLastDockerVersionChange(workingDir, shell)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -116,3 +140,23 @@ func doBuild(opts buildOpts) (*dag.DAG, error) {
logrus.Info("Build process completed")
return DAG, nil
}

// findDockerRootDir iterates over the buildPath to find the first matching directory containing
// a .docker-version file. We consider this directory as the root docker directory containing all the dockerfiles.
func findDockerRootDir(workingDir, buildPath string) (string, error) {
searchPath := buildPath
for {
if _, err := os.Stat(path.Join(workingDir, searchPath, versn.DockerVersionFilename)); err == nil {
return searchPath, nil
} else if !errors.Is(err, os.ErrNotExist) {
return "", err
}

dir, _ := path.Split(buildPath)
if dir == "" {
return "", fmt.Errorf("searching for docker root dir failed, no directory in %s "+
"contains a %s file", buildPath, versn.DockerVersionFilename)
}
searchPath = dir
}
}
8 changes: 7 additions & 1 deletion cmd/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package main
import (
"log"

"github.com/sirupsen/logrus"

cli "github.com/jawher/mow.cli"
"github.com/radiofrance/dib/graphviz"
"github.com/radiofrance/dib/preflight"
Expand All @@ -21,7 +23,11 @@ func cmdGraph(cmd *cli.Cmd) {
if err != nil {
log.Fatal(err)
}
if err := graphviz.GenerateGraph(DAG, opts.outputDir); err != nil {
workingDir, err := getWorkingDir()
if err != nil {
logrus.Fatalf("failed to get current working directory: %v", err)
}
if err := graphviz.GenerateGraph(DAG, workingDir); err != nil {
log.Fatal(err)
}
}
Expand Down
28 changes: 8 additions & 20 deletions cmd/options.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package main

import (
"log"
"os"

cli "github.com/jawher/mow.cli"
)

Expand All @@ -14,29 +11,20 @@ type buildOpts struct {
retagLatest bool
generateGraph bool
localOnly bool
buildDir string
inputDir string
outputDir string
buildPath string
registryURL string
}

func defaultOpts(opts *buildOpts, cmd *cli.Cmd) {
pwd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
cmd.Spec = "[OPTIONS] [BUILD_PATH]"

//nolint:lll
desc := `Path to the directory containing the Dockerfiles, relative to the input directory specified by --input.
All Dockerfiles within this directory will be recursively found and added to the build graph.
You can provide any subdirectory if you want to focus on a reduced set of images, as long as it has at least one Dockerfile in it.`
desc := `Path to the directory you want to build All Dockerfiles within this directory will be recursively
found and added to the build graph. You can provide any subdirectory if you want to focus on a reduced set of images,
as long as it has at least one Dockerfile in it.
cmd.Spec = "[OPTIONS] [BUILD_PATH]"
cmd.StringArgPtr(&opts.buildDir, "BUILD_PATH", "docker", desc)
It is also expected that one of the director in this path contains a .docker-version file. This directory will
be considered as the root directory for the hash generation and comparison`

cmd.StringArgPtr(&opts.buildPath, "BUILD_PATH", "docker", desc)
cmd.StringOptPtr(&opts.registryURL, "registry-url", defaultRegistryURL, "Docker registry URL where images are stored.")
cmd.StringOptPtr(&opts.outputDir, "o output", pwd,
"Output directory where .dot and .png files will be generated")
cmd.StringOptPtr(&opts.inputDir, "i input", pwd,
"Root directory where docker directory and .dockerversion files are stored")
}
10 changes: 5 additions & 5 deletions dag/dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,31 @@ func (dag *DAG) GenerateDAG(buildPath string, registryPrefix string) {
return err
}
if dockerfile.IsDockerfile(filePath) {
dockerfile, err := dockerfile.ParseDockerfile(filePath)
dckfile, err := dockerfile.ParseDockerfile(filePath)
if err != nil {
return err
}

skipBuild, hasSkipLabel := dockerfile.Labels["skipbuild"]
skipBuild, hasSkipLabel := dckfile.Labels["skipbuild"]
if hasSkipLabel && skipBuild == "true" {
return nil
}
imageShortName, hasSkipLabel := dockerfile.Labels["name"]
imageShortName, hasSkipLabel := dckfile.Labels["name"]
if !hasSkipLabel {
return fmt.Errorf("missing label \"image\" in Dockerfile at path \"%s\"", filePath)
}
img := &Image{
Name: fmt.Sprintf("%s/%s", registryPrefix, imageShortName),
ShortName: imageShortName,
Dockerfile: dockerfile,
Dockerfile: dckfile,
RebuildCond: sync.NewCond(&sync.Mutex{}),
Builder: dag.Builder,
Registry: dag.Registry,
TestRunners: dag.TestRunners,
Tagger: dag.Tagger,
}

allParents[img.Name] = dockerfile.From
allParents[img.Name] = dckfile.From
cache[img.Name] = img
}
return nil
Expand Down
8 changes: 4 additions & 4 deletions version/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ func GetDiffSinceLastDockerVersionChange(repositoryPath string, exec exec.Execut
dockerVersionContent, err := getDockerVersionContentForHash(repo, lastChangedDockerVersionHash)
if err != nil {
return "", nil, fmt.Errorf("failed to get %s content for hash %s",
dockerVersionFilename, lastChangedDockerVersionHash.String())
DockerVersionFilename, lastChangedDockerVersionHash.String())
}

return dockerVersionContent, fullPathDiffs, nil
return strings.TrimSuffix(dockerVersionContent, "\n"), fullPathDiffs, nil
}

func getDockerVersionContentForHash(repo *git.Repository, lastChangedDockerVersionHash plumbing.Hash) (string, error) {
Expand All @@ -61,7 +61,7 @@ func getDockerVersionContentForHash(repo *git.Repository, lastChangedDockerVersi
if err != nil {
return "", err
}
file, err := tree.File(dockerVersionFilename)
file, err := tree.File(DockerVersionFilename)
if err != nil {
return "", err
}
Expand All @@ -73,7 +73,7 @@ func getDockerVersionContentForHash(repo *git.Repository, lastChangedDockerVersi
}

func getLastChangedDockerVersion(repository *git.Repository) (plumbing.Hash, error) {
filename := dockerVersionFilename
filename := DockerVersionFilename
commitLog, err := repository.Log(&git.LogOptions{
FileName: &filename,
})
Expand Down
4 changes: 4 additions & 0 deletions version/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ func humanReadableHashFn(files []string, open func(string) (io.ReadCloser, error
if strings.Contains(file, "\n") {
return "", errors.New("dirhash: filenames with newlines are not supported")
}
if file == DockerVersionFilename {
// We ignore the hash file itself in the hash process
continue
}
readCloser, err := open(file)
if err != nil {
return "", err
Expand Down
8 changes: 4 additions & 4 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import (
"strings"
)

const dockerVersionFilename = ".docker-version"
const DockerVersionFilename = ".docker-version"

// CheckDockerVersionIntegrity verifies the consistency of the version hash
// contained in the .docker-version file against the revision hash from git.
// It returns the version if the verification is successful.
func CheckDockerVersionIntegrity(rootPath, buildPath string) (string, error) {
fileVersion, err := getDockerVersionFromFile(path.Join(rootPath, dockerVersionFilename))
func CheckDockerVersionIntegrity(buildPath string) (string, error) {
fileVersion, err := getDockerVersionFromFile(path.Join(buildPath, DockerVersionFilename))
if err != nil {
return "", err
}

dockerVersionHash, err := GetDockerVersionHash(path.Join(rootPath, buildPath))
dockerVersionHash, err := GetDockerVersionHash(buildPath)
if err != nil {
return "", fmt.Errorf("could not obtain docker-version hash: %w", err)
}
Expand Down

0 comments on commit ce6dc87

Please sign in to comment.