UNPKG

3.2 kBJavaScriptView Raw
1// 'sanbashi' is a word in Japanese that refers to a pier or dock, usually very large in size, such as found in Tokyo's O-daiba region
2
3let Glob = require('glob')
4let Path = require('path')
5let Inquirer = require('inquirer')
6const Child = require('child_process')
7const log = require('./log')
8
9const DOCKERFILE_REGEX = /\bDockerfile(.\w*)?$/
10let Sanbashi = function () {}
11
12Sanbashi.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
27Sanbashi.getJobs = function (resourceRoot, dockerfiles) {
28 return dockerfiles
29 // convert all Dockerfiles into job Objects
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 // prefer closer Dockerfiles, then prefer Dockerfile over Dockerfile.web
43 .sort((a, b) => {
44 return a.depth - b.depth || a.postfix - b.postfix
45 })
46 // group all Dockerfiles for the same process type together
47 .reduce((jobs, job) => {
48 jobs[job.name] = jobs[job.name] || []
49 jobs[job.name].push(job)
50 return jobs
51 }, {})
52}
53
54Sanbashi.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
74Sanbashi.filterByProcessType = function (jobs, procs) {
75 let filteredJobs = {}
76 procs.forEach((processType) => {
77 filteredJobs[processType] = jobs[processType]
78 })
79 return filteredJobs
80}
81
82Sanbashi.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
89Sanbashi.pushImage = function (resource, verbose) {
90 let args = ['push', resource]
91 log(verbose, args)
92 return Sanbashi.cmd('docker', args)
93}
94
95Sanbashi.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
105module.exports = Sanbashi