- package build
-
- import (
- "fmt"
- "path"
- "sort"
- )
-
- // ApplyUser wraps any build.Copy instructions as build.CopyAs using the given
- // UID/GID.
- //
- func ApplyUser(uid uint, gid uint, instructions []Instruction) []Instruction {
- applied := make([]Instruction, len(instructions))
-
- for i, instruction := range instructions {
- switch instruction.(type) {
- case Copy, CopyFrom:
- applied[i] = CopyAs{uid, gid, instruction}
- default:
- applied[i] = instruction
- }
- }
-
- return applied
- }
-
- // Chown returns a build.Run instruction for setting ownership on the given
- // path.
- //
- func Chown(uid uint, gid uint, path string) Run {
- return Run{"chown %s:%s", []string{fmt.Sprint(uid), fmt.Sprint(gid), path}}
- }
-
- // CreateDirectories returns a build.Run instruction for creating all the
- // given directories.
- //
- func CreateDirectories(paths []string) Run {
- return Run{"mkdir -p", paths}
- }
-
- // CreateDirectory returns a build.Run instruction for creating the given
- // directory.
- //
- func CreateDirectory(path string) Run {
- return CreateDirectories([]string{path})
- }
-
- // CreateUser returns build.Run instructions for creating the given user
- // account and group.
- //
- func CreateUser(name string, uid uint, gid uint) []Run {
- return []Run{
- {"groupadd -o -g %s -r", []string{fmt.Sprint(gid), name}},
- {"useradd -o -m -d %s -r -g %s -u %s", []string{homeDir(name), name, fmt.Sprint(uid), name}},
- }
- }
-
- // Home returns a build.Env instruction for setting the user's home directory.
- //
- func Home(name string) Env {
- return Env{map[string]string{"HOME": homeDir(name)}}
- }
-
- func homeDir(name string) string {
- if name == "root" {
- return "/root"
- }
-
- return "/home/" + name
- }
-
- // SortFilesByDir returns both the given files indexed by parent directory and
- // a sorted slice of those parent directories. The latter is useful in
- // ensuring deterministic iteration since the ordering of map keys is not
- // guaranteed.
- //
- func SortFilesByDir(files []string) ([]string, map[string][]string) {
- bydir := make(map[string][]string)
-
- for _, file := range files {
- dir := path.Dir(file) + "/"
- file = path.Clean(file)
-
- if dirfiles, found := bydir[dir]; found {
- bydir[dir] = append(dirfiles, file)
- } else {
- bydir[dir] = []string{file}
- }
- }
-
- dirs := make([]string, len(bydir))
- i := 0
-
- for dir := range bydir {
- dirs[i] = dir
- i++
- }
-
- sort.Strings(dirs)
-
- return dirs, bydir
- }
-
- // SyncFiles returns build instructions to copy over the given files after
- // creating their parent directories. Parent directories are created in a
- // sorted order.
- //
- func SyncFiles(files []string, dest string) []Instruction {
- if len(files) < 1 {
- return []Instruction{}
- }
-
- dirs, bydir := SortFilesByDir(files)
- mkdirs := []string{}
- copies := make([]Instruction, len(dirs))
-
- // make project subdirectories for requirements files if necessary, and
- // copy in requirements files
- for i, dir := range dirs {
- fulldir := dest + "/" + dir
- fulldir = path.Clean(fulldir) + "/"
-
- if dir != "./" {
- mkdirs = append(mkdirs, fulldir)
- }
-
- copies[i] = Copy{bydir[dir], fulldir}
- }
-
- ins := []Instruction{}
-
- if len(mkdirs) > 0 {
- ins = append(ins, CreateDirectories(mkdirs))
- }
-
- return append(ins, copies...)
- }
|