1 |
|
2 |
|
3 | let Glob = require('glob')
|
4 | let Path = require('path')
|
5 | let Inquirer = require('inquirer')
|
6 | const Child = require('child_process')
|
7 | const log = require('./log')
|
8 |
|
9 | const DOCKERFILE_REGEX = /\bDockerfile(.\w*)?$/
|
10 | let Sanbashi = function () {}
|
11 |
|
12 | Sanbashi.getDockerfiles = function (rootdir, recursive) {
|
13 | let match = recursive ? './**/Dockerfile?(.)*' : 'Dockerfile*'
|
14 | let dockerfiles = Glob.sync(match, {
|
15 | cwd: rootdir,
|
16 | nonull: false,
|
17 | nodir: true
|
18 | })
|
19 | if (recursive) {
|
20 | dockerfiles = dockerfiles.filter(df => df.match(/Dockerfile\.[\w]+/))
|
21 | } else {
|
22 | dockerfiles = dockerfiles.filter(df => df.match(/Dockerfile$/))
|
23 | }
|
24 | return dockerfiles.map(file => Path.join(rootdir, file))
|
25 | }
|
26 |
|
27 | Sanbashi.getJobs = function (resourceRoot, dockerfiles) {
|
28 | return dockerfiles
|
29 |
|
30 | .map((dockerfile) => {
|
31 | let match = dockerfile.match(DOCKERFILE_REGEX)
|
32 | if (!match) return
|
33 | let proc = (match[1] || '.standard').slice(1)
|
34 | return {
|
35 | name: proc,
|
36 | resource: `${ resourceRoot }/${ proc }`,
|
37 | dockerfile: dockerfile,
|
38 | postfix: Path.basename(dockerfile) === 'Dockerfile' ? 0 : 1,
|
39 | depth: Path.normalize(dockerfile).split(Path.sep).length
|
40 | }
|
41 | })
|
42 |
|
43 | .sort((a, b) => {
|
44 | return a.depth - b.depth || a.postfix - b.postfix
|
45 | })
|
46 |
|
47 | .reduce((jobs, job) => {
|
48 | jobs[job.name] = jobs[job.name] || []
|
49 | jobs[job.name].push(job)
|
50 | return jobs
|
51 | }, {})
|
52 | }
|
53 |
|
54 | Sanbashi.chooseJobs = async function (jobs) {
|
55 | let chosenJobs = []
|
56 | for (let processType in jobs) {
|
57 | let group = jobs[processType]
|
58 | if (group.length > 1) {
|
59 | let prompt = {
|
60 | type: 'list',
|
61 | name: processType,
|
62 | choices: group.map(j => j.dockerfile),
|
63 | message: `Found multiple Dockerfiles with process type ${processType}. Please choose one to build and push `
|
64 | }
|
65 | let answer = await Inquirer.prompt(prompt)
|
66 | chosenJobs.push(group.find(o => o.dockerfile === answer[processType]))
|
67 | } else {
|
68 | chosenJobs.push(group[0])
|
69 | }
|
70 | }
|
71 | return chosenJobs
|
72 | }
|
73 |
|
74 | Sanbashi.filterByProcessType = function (jobs, procs) {
|
75 | let filteredJobs = {}
|
76 | procs.forEach((processType) => {
|
77 | filteredJobs[processType] = jobs[processType]
|
78 | })
|
79 | return filteredJobs
|
80 | }
|
81 |
|
82 | Sanbashi.buildImage = function (dockerfile, resource, verbose) {
|
83 | let cwd = Path.dirname(dockerfile)
|
84 | let args = ['build', '-f', dockerfile, '-t', resource, cwd]
|
85 | log(verbose, args)
|
86 | return Sanbashi.cmd('docker', args)
|
87 | }
|
88 |
|
89 | Sanbashi.pushImage = function (resource, verbose) {
|
90 | let args = ['push', resource]
|
91 | log(verbose, args)
|
92 | return Sanbashi.cmd('docker', args)
|
93 | }
|
94 |
|
95 | Sanbashi.cmd = function (cmd, args) {
|
96 | return new Promise((resolve, reject) => {
|
97 | Child.spawn(cmd, args, {stdio: 'inherit'})
|
98 | .on('exit', (code, signal) => {
|
99 | if (signal || code) reject(signal || code)
|
100 | else resolve()
|
101 | })
|
102 | })
|
103 | }
|
104 |
|
105 | module.exports = Sanbashi
|