~dricottone/simple-builder

simple-builder/main.go -rw-r--r-- 3.8 KiB
5efee8c6Dominic Ricottone Update 6 months ago
                                                                                
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package main

import (
	"flag"
	"fmt"
)

var (
	verbose = flag.Bool("verbose", false, "Show debugging messages")
	build = flag.Bool("build", false, "Build packages")
	summary = flag.Bool("summary", false, "Summarize packages to build")
	source = flag.String("source", "./src", "Directory of package sources")
	destination = flag.String("destination", "./pkg", "Directory of packages")
	architecture = flag.String("architecture", "detected from repository", "architecture to build")
	repository = flag.String("repository", "", "Connection string for the remote package repository")
)

// Conditionally print a string.
func print_if(condition bool, str string) {
	if (condition == true) {
		fmt.Println(str)
	}
}

// Print debugging information if -verbose was passed to the program.
func debug(str string) {
	print_if(*verbose, str)
}

// Identify Packages in the package source directory.
func list_package_sources(local_dir string) []Package {
	packages, err := walk_package_sources(local_dir)
	if (err != nil) {
		debug(err.Error())
	}

	if (*verbose == true) {
		dump_apkbuilds(packages, "DEBUG-MAIN")
	}

	return packages
}

// Identify Packages in the repository.
func list_repository(remote_dir string) []Package {
	packages, err := fetch_repository_listing(remote_dir)
	if (err != nil) {
		debug(err.Error())
	}

	if (*verbose == true) {
		dump_apkbuilds(packages, "DEBUG-MAIN")
	}

	return packages
}

// Compare Packages between the package source directory and the repository.
func compare_lists(local_dir, remote_dir string) ([]Package, error) {
	queue := []Package{}
	had_errors := false

	package_sources := list_package_sources(local_dir)
	repository := list_repository(remote_dir)

	for i, _ := range package_sources {
		err := find_builds(&package_sources[i], &repository)
		if (err != nil) {
			return nil, err
		}

		if (package_sources[i].Build == true) {
			queue = append(queue, package_sources[i])
		}

		if (package_sources[i].Error == true) {
			print_if(!had_errors, "Warnings:")
			had_errors = true
			fmt.Printf("%s %s - %s\n", package_sources[i].Name, package_sources[i].Version, package_sources[i].Message)
		}
	}

	err := find_breaking_builds(&queue)
	if (err != nil) {
		return nil, err
	}

	err = sort_queue(&queue)
	if (err != nil) {
		return nil, err
	}

	return queue, nil
}

// Sort the Package list in-place.
func sort_queue(packages *[]Package) error {
	visited := []string{}
	resolved := []Package{}

	for i, _ := range (*packages) {
		err := resolve_dependencies(&resolved, packages, i, &visited)
		if (err != nil) {
			return err
		}
	}

	(*packages) = resolved
	return nil
}

// Build Packages.
func build_packages(packages []Package, source, destination, arch, repository string) error {
	for _, pkg := range packages {
		debug(fmt.Sprintf("Building %s...", pkg.Name))
		err := build_package(pkg, source, destination, arch)
		if (err != nil) {
			return err
		}

		debug(fmt.Sprintf("Pushing %s...", pkg.Name))
		local_dir := expected_apkdir(destination, arch)
		err = push_package(pkg, local_dir, repository)
		if (err != nil) {
			return err
		}
	}

	return nil
}

// Print details about Packages queued for build.
func summarize_packages(packages []Package) {
	if (len(packages) == 0) {
		fmt.Println("Nothing to do")
	} else {
		fmt.Println("Packages to build:")
		for _, p := range packages {
			fmt.Printf("  %s %s - %s\n", p.Name, p.Version, p.Message)
		}
		fmt.Println("To start building, pass the `-build` option")
	}
}

func main() {
	flag.Parse()
	src := clean_source(*source)
	pkg := clean_destination(*destination)
	repo := clean_repository(*repository)
	arch := clean_architecture(*architecture, repo)

	packages, err := compare_lists(src, repo)
	if (err != nil) {
		panic(err)
	}

	if (*build == true) {
		err = build_packages(packages, src, pkg, arch, repo)
		if (err != nil) {
			panic(err)
		}
	} else {
		summarize_packages(packages)
	}
}