]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file | |
3 | // distributed with this work for additional information | |
4 | // regarding copyright ownership. The ASF licenses this file | |
5 | // to you under the Apache License, Version 2.0 (the | |
6 | // "License"); you may not use this file except in compliance | |
7 | // with the License. You may obtain a copy of the License at | |
8 | // | |
9 | // http://www.apache.org/licenses/LICENSE-2.0 | |
10 | // | |
11 | // Unless required by applicable law or agreed to in writing, | |
12 | // software distributed under the License is distributed on an | |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
14 | // KIND, either express or implied. See the License for the | |
15 | // specific language governing permissions and limitations | |
16 | // under the License. | |
17 | ||
18 | const fs = require('fs'); | |
19 | const path = require(`path`); | |
20 | const pump = require(`stream`).pipeline; | |
21 | const child_process = require(`child_process`); | |
22 | const { targets, modules } = require('./argv'); | |
23 | const { | |
24 | ReplaySubject, | |
25 | empty: ObservableEmpty, | |
26 | throwError: ObservableThrow, | |
27 | fromEvent: ObservableFromEvent | |
28 | } = require('rxjs'); | |
29 | const { | |
30 | share, | |
31 | flatMap, | |
32 | takeUntil, | |
33 | defaultIfEmpty, | |
34 | mergeWith, | |
35 | } = require('rxjs/operators'); | |
36 | const asyncDone = require('util').promisify(require('async-done')); | |
37 | ||
38 | const mainExport = `Arrow`; | |
39 | const npmPkgName = `apache-arrow`; | |
40 | const npmOrgName = `@${npmPkgName}`; | |
41 | ||
42 | const releasesRootDir = `targets`; | |
43 | const knownTargets = [`es5`, `es2015`, `esnext`]; | |
44 | const knownModules = [`cjs`, `esm`, `cls`, `umd`]; | |
45 | const tasksToSkipPerTargetOrFormat = { | |
46 | src: { clean: true, build: true }, | |
47 | cls: { test: true, package: true } | |
48 | }; | |
49 | const packageJSONFields = [ | |
50 | `version`, `license`, `description`, | |
51 | `author`, `homepage`, `repository`, | |
52 | `bugs`, `keywords`, `dependencies`, | |
53 | `bin` | |
54 | ]; | |
55 | ||
56 | const metadataFiles = [`LICENSE.txt`, `NOTICE.txt`, `README.md`].map((filename) => { | |
57 | let prefixes = [`./`, `../`]; | |
58 | let p = prefixes.find((prefix) => { | |
59 | try { | |
60 | fs.statSync(path.resolve(path.join(prefix, filename))); | |
61 | } catch (e) { return false; } | |
62 | return true; | |
63 | }); | |
64 | if (!p) { | |
65 | throw new Error(`Couldn't find ${filename} in ./ or ../`); | |
66 | } | |
67 | return path.join(p, filename); | |
68 | }); | |
69 | ||
70 | // see: https://github.com/google/closure-compiler/blob/c1372b799d94582eaf4b507a4a22558ff26c403c/src/com/google/javascript/jscomp/CompilerOptions.java#L2988 | |
71 | const gCCLanguageNames = { | |
72 | es5: `ECMASCRIPT5`, | |
73 | es2015: `ECMASCRIPT_2015`, | |
74 | es2016: `ECMASCRIPT_2016`, | |
75 | es2017: `ECMASCRIPT_2017`, | |
76 | es2018: `ECMASCRIPT_2018`, | |
77 | es2019: `ECMASCRIPT_2019`, | |
78 | esnext: `ECMASCRIPT_NEXT` | |
79 | }; | |
80 | ||
81 | function taskName(target, format) { | |
82 | return !format ? target : `${target}:${format}`; | |
83 | } | |
84 | ||
85 | function packageName(target, format) { | |
86 | return !format ? target : `${target}-${format}`; | |
87 | } | |
88 | ||
89 | function tsconfigName(target, format) { | |
90 | return !format ? target : `${target}.${format}`; | |
91 | } | |
92 | ||
93 | function targetDir(target, format) { | |
94 | return path.join(releasesRootDir, ...(!format ? [target] : [target, format])); | |
95 | } | |
96 | ||
97 | function shouldRunInChildProcess(target, format) { | |
98 | // If we're building more than one module/target, then yes run this task in a child process | |
99 | if (targets.length > 1 || modules.length > 1) { return true; } | |
100 | // If the target we're building *isn't* the target the gulp command was configured to run, then yes run that in a child process | |
101 | if (targets[0] !== target || modules[0] !== format) { return true; } | |
102 | // Otherwise no need -- either gulp was run for just one target, or we've been spawned as the child of a multi-target parent gulp | |
103 | return false; | |
104 | } | |
105 | ||
106 | const gulp = path.join(path.parse(require.resolve(`gulp`)).dir, `bin/gulp.js`); | |
107 | function spawnGulpCommandInChildProcess(command, target, format) { | |
108 | const args = [gulp, command, '-t', target, '-m', format, `--silent`]; | |
109 | const opts = { | |
110 | stdio: [`ignore`, `inherit`, `inherit`], | |
111 | env: { ...process.env, NODE_NO_WARNINGS: `1` } | |
112 | }; | |
113 | return asyncDone(() => child_process.spawn(`node`, args, opts)) | |
114 | .catch((e) => { throw `Error in "${command}:${taskName(target, format)}" task`; }); | |
115 | } | |
116 | ||
117 | const logAndDie = (e) => { if (e) { process.exit(1) } }; | |
118 | function observableFromStreams(...streams) { | |
119 | if (streams.length <= 0) { return ObservableEmpty(); } | |
120 | const pumped = streams.length <= 1 ? streams[0] : pump(...streams, logAndDie); | |
121 | const fromEvent = ObservableFromEvent.bind(null, pumped); | |
122 | const streamObs = fromEvent(`data`).pipe( | |
123 | mergeWith(fromEvent(`error`).pipe(flatMap((e) => ObservableThrow(e)))), | |
124 | takeUntil(fromEvent(`end`).pipe(mergeWith(fromEvent(`close`)))), | |
125 | defaultIfEmpty(`empty stream`), | |
126 | share({ connector: () => new ReplaySubject(), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }) | |
127 | ); | |
128 | streamObs.stream = pumped; | |
129 | streamObs.observable = streamObs; | |
130 | return streamObs; | |
131 | } | |
132 | ||
133 | function* combinations(_targets, _modules) { | |
134 | const targets = known(knownTargets, _targets || [`all`]); | |
135 | const modules = known(knownModules, _modules || [`all`]); | |
136 | ||
137 | if (_targets.includes(`src`)) { | |
138 | yield [`src`, ``]; | |
139 | return; | |
140 | } | |
141 | ||
142 | if (_targets.includes(`all`) && _modules.includes(`all`)) { | |
143 | yield [`ts`, ``]; | |
144 | yield [`src`, ``]; | |
145 | yield [npmPkgName, ``]; | |
146 | } | |
147 | ||
148 | for (const format of modules) { | |
149 | for (const target of targets) { | |
150 | yield [target, format]; | |
151 | } | |
152 | } | |
153 | ||
154 | function known(known, values) { | |
155 | return values.includes(`all`) ? known | |
156 | : values.includes(`src`) ? [`src`] | |
157 | : Object.keys( | |
158 | values.reduce((map, arg) => (( | |
159 | (known.includes(arg)) && | |
160 | (map[arg.toLowerCase()] = true) | |
161 | || true) && map | |
162 | ), {}) | |
163 | ).sort((a, b) => known.indexOf(a) - known.indexOf(b)); | |
164 | } | |
165 | } | |
166 | ||
167 | const publicModulePaths = (dir) => [ | |
168 | `${dir}/${mainExport}.dom.js`, | |
169 | `${dir}/util/int.js`, | |
170 | `${dir}/compute/predicate.js`, | |
171 | ]; | |
172 | ||
173 | const esmRequire = require(`esm`)(module, { | |
174 | mode: `auto`, | |
175 | cjs: { | |
176 | /* A boolean for storing ES modules in require.cache. */ | |
177 | cache: true, | |
178 | /* A boolean for respecting require.extensions in ESM. */ | |
179 | extensions: true, | |
180 | /* A boolean for __esModule interoperability. */ | |
181 | interop: true, | |
182 | /* A boolean for importing named exports of CJS modules. */ | |
183 | namedExports: true, | |
184 | /* A boolean for following CJS path rules in ESM. */ | |
185 | paths: true, | |
186 | /* A boolean for __dirname, __filename, and require in ESM. */ | |
187 | vars: true, | |
188 | } | |
189 | }); | |
190 | ||
191 | module.exports = { | |
192 | mainExport, npmPkgName, npmOrgName, metadataFiles, packageJSONFields, | |
193 | ||
194 | knownTargets, knownModules, tasksToSkipPerTargetOrFormat, gCCLanguageNames, | |
195 | ||
196 | taskName, packageName, tsconfigName, targetDir, combinations, observableFromStreams, | |
197 | publicModulePaths, esmRequire, shouldRunInChildProcess, spawnGulpCommandInChildProcess, | |
198 | ||
199 | targetAndModuleCombinations: [...combinations(targets, modules)] | |
200 | }; |