๐Ÿ“ฆ pengsrc / docker-tools

๐Ÿ“„ pack.go ยท 111 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111package build

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"time"

	"github.com/pengsrc/docker-tools/constants"
)

// CreatePackage creates source package.
func CreatePackage(
	sourceDir string, includes []string, excludes []string,
	useGitArchive bool, tagOrCommitHash string,
) (packagePath string, err error) {
	f, err := ioutil.TempFile(os.TempDir(), fmt.Sprintf("%d-", time.Now().Unix()))
	if err != nil {
		return
	}
	defer f.Close()

	// Check tar or gtar.
	tar := "tar"
	if CommandExists(constants.GNUPrefix + tar) {
		tar = constants.GNUPrefix + tar
	} else {
		if !CommandExists(tar) {
			err = fmt.Errorf(`command "%s" not found`, tar)
			return
		}
	}

	// Check gzip.
	gzip := "gzip"
	if !CommandExists(gzip) {
		err = fmt.Errorf(`command "%s" not found`, gzip)
		return
	}

	// Commands to execute later.
	cmds := []*exec.Cmd{}

	// Create tarball.
	if useGitArchive {
		// Check git.
		git := "git"
		if !CommandExists(git) {
			err = fmt.Errorf(`command "%s" not found`, git)
			return
		}

		command := exec.Command(git, "archive", "--format", "tar", tagOrCommitHash)
		command.Stdout = f
		cmds = append(cmds, exec.Command("pwd"))
		cmds = append(cmds, command)
	} else {
		cmds = append(cmds, exec.Command(tar, "--transform", "s,^./,,g", "-cf", f.Name(), "."))
	}

	// Include directories.
	if len(includes) > 0 {
		args := []string{"--transform", "s,^./,,g", "-rf", f.Name()}
		args = append(args, includes...)
		cmds = append(cmds, exec.Command(tar, args...))
	}

	// Exclude directories.
	if len(excludes) > 0 {
		args := []string{"--delete", "-f", f.Name()}
		args = append(args, excludes...)
		cmds = append(cmds, exec.Command(tar, args...))
	}

	// Compress tarball.
	mv := "mv"
	if !CommandExists(mv) {
		err = fmt.Errorf(`command "%s" not found`, mv)
		return
	}

	cmds = append(cmds, exec.Command(gzip, "-9f", f.Name()))
	cmds = append(cmds, exec.Command(mv, fmt.Sprintf("%s.gz", f.Name()), f.Name()))

	// List tarball.
	cmds = append(cmds, exec.Command(tar, "-tf", f.Name()))

	// Execute commands.
	for _, cmd := range cmds {
		fmt.Printf("Executing: %s %v\n", cmd.Path, cmd.Args)
		cmd.Dir = sourceDir
		if cmd.Stdin == nil {
			cmd.Stdin = os.Stdin
		}
		if cmd.Stdout == nil {
			cmd.Stdout = os.Stdout
		}
		if cmd.Stderr == nil {
			cmd.Stderr = os.Stderr
		}
		err = cmd.Run()
		if err != nil {
			return
		}
	}

	packagePath = f.Name()
	return
}