// BuildFile builds the specified docker file in the context of the specified // directory. func BuildFile(dockerfile, dir, tag string) string { if !file.Exists(dockerfile) { cli.Fatalf("File does not exist: %s", dockerfile) } dir = path.Resolve(dir) localDockerfile := ".SousDockerfile" if file.Exists(localDockerfile) { file.Remove(localDockerfile) } file.RemoveOnExit(localDockerfile) // If there is a .gitignore, but no .dockerignore, link it as .dockerignore if file.Exists(".gitignore") { if file.Exists(".dockerignore") { cli.Warn("./.dockerignore found, it is recommended to remove this so Sous can use your .gitignore") } else { file.TemporaryLink(".gitignore", ".dockerignore") // We try to clean this file up early, in preperation for the next build step defer file.Remove(".dockerignore") } } file.TemporaryLink(dockerfile, localDockerfile) // We try to clean the local Dockerfile up early, in preperation for the next build step defer file.Remove(localDockerfile) return dockerCmd("build", "-f", localDockerfile, "-t", tag, dir).Out() }
func (s *Sous) AssembleTargetContext(targetName string) (Target, *Context) { packs := s.Packs p := DetectProjectType(packs) if p == nil { cli.Fatalf("no buildable project detected") } pack := CompiledPack{Pack: p} target, ok := pack.GetTarget(targetName) if !ok { cli.Fatalf("The %s build pack does not support %s", pack, targetName) } if fatal := CheckForProblems(pack.Pack); fatal { cli.Fatal() } context := GetContext(targetName) err := target.Check() if err != nil { cli.Fatalf("unable to %s %s project: %s", targetName, pack, err) } // If the pack specifies a version, check it matches the tagged version packAppVersion := strings.Split(pack.AppVersion(), "+")[0] if packAppVersion != "" { pv := version.Version(packAppVersion) gv := version.Version(context.BuildVersion.MajorMinorPatch) if !pv.Version.LimitedEqual(gv.Version) { cli.Warn("using latest git tagged version %s; your code reports version %s, which is ignored", gv, pv) } } return target, context }
// buildVersion constructs a BuildVersion from git info. func buildVersion(i *git.Info) *BuildVersion { // Try to parse the nearest tag as a version. If it isn't a valid version, // we just give up and return a default for now. // TODO: It's possible to walk through the tags in order of distance from // the current commit, to find the nearest semver tag, so consider doing // that, if this becomes an issue. if i.NearestTag == "" { cli.Warn("No git tags found in the format X.Y.Z, defaulting to v0.0.0", i.NearestTag) return defaultBuildVersion(i.CommitSHA) } v, err := version.NewVersion(i.NearestTag) if err != nil { cli.Warn("Latest git tag '%s' not in the format X.Y.Z, defaulting to v0.0.0", i.NearestTag) return defaultBuildVersion(i.CommitSHA) } if i.NearestTagSHA == i.CommitSHA { // We're building an exact version return &BuildVersion{MajorMinorPatch: v.String()} } // We're building a commit between named versions, so add the commit SHA return &BuildVersion{MajorMinorPatch: v.String(), PlusRevision: i.CommitSHA} }
func (s *Sous) BuildImage(t Target, c *Context) { c.IncrementBuildNumber() if file.Exists("Dockerfile") { cli.Warn("./Dockerfile ignored by sous; use `sous dockerfile %s` to see the Dockerfile in effect", t.Name()) } if prebuilder, ok := t.(PreDockerBuilder); ok { prebuilder.PreDockerBuild(c) } // NB: Always rebuild the Dockerfile after running pre-build, since pre-build // may update target state to reflect things like copied file locations etc. c.SaveFile(s.Dockerfile(t, c).Render(), "Dockerfile") docker.BuildFile(c.FilePath("Dockerfile"), ".", c.DockerTag()) c.Commit() }
func Push(sous *core.Sous, args []string) { target := "app" if len(args) != 0 { target = args[0] } core.RequireGit() core.RequireDocker() if err := git.AssertCleanWorkingTree(); err != nil { cli.Warn("Dirty working tree: %s", err) } _, context := sous.AssembleTargetContext(target) tag := context.DockerTag() if !docker.ImageExists(tag) { cli.Fatalf("No built image available; try building first") } docker.Push(tag) name := context.CanonicalPackageName() cli.Successf("Successfully pushed %s v%s as %s", name, context.BuildVersion, context.DockerTag()) }
func Build(sous *core.Sous, args []string) { targetName := "app" if len(args) != 0 { targetName = args[0] } core.RequireGit() core.RequireDocker() if err := git.AssertCleanWorkingTree(); err != nil { cli.Warn("Dirty working tree: %s", err) } target, context := sous.AssembleTargetContext(targetName) built, _ := sous.RunTarget(target, context) if !built { cli.Successf("Already built: %s", context.DockerTag()) } name := context.CanonicalPackageName() cli.Successf("Successfully built %s v%s as %s", name, context.BuildVersion, context.DockerTag()) }