@expo/steps 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/bin/set-output +16 -0
- package/dist_commonjs/BuildConfig.cjs +50 -0
- package/dist_commonjs/BuildConfig.d.ts +25 -0
- package/dist_commonjs/BuildConfig.js.map +1 -0
- package/dist_commonjs/BuildConfigParser.cjs +87 -0
- package/dist_commonjs/BuildConfigParser.d.ts +14 -0
- package/dist_commonjs/BuildConfigParser.js.map +1 -0
- package/dist_commonjs/BuildStep.cjs +146 -0
- package/dist_commonjs/BuildStep.d.ts +40 -0
- package/dist_commonjs/BuildStep.js.map +1 -0
- package/dist_commonjs/BuildStepContext.cjs +32 -0
- package/dist_commonjs/BuildStepContext.d.ts +13 -0
- package/dist_commonjs/BuildStepContext.js.map +1 -0
- package/dist_commonjs/BuildStepInput.cjs +36 -0
- package/dist_commonjs/BuildStepInput.d.ts +17 -0
- package/dist_commonjs/BuildStepInput.js.map +1 -0
- package/dist_commonjs/BuildStepOutput.cjs +29 -0
- package/dist_commonjs/BuildStepOutput.d.ts +15 -0
- package/dist_commonjs/BuildStepOutput.js.map +1 -0
- package/dist_commonjs/BuildWorkflow.cjs +15 -0
- package/dist_commonjs/BuildWorkflow.d.ts +8 -0
- package/dist_commonjs/BuildWorkflow.js.map +1 -0
- package/dist_commonjs/BuildWorkflowValidator.cjs +76 -0
- package/dist_commonjs/BuildWorkflowValidator.d.ts +8 -0
- package/dist_commonjs/BuildWorkflowValidator.js.map +1 -0
- package/dist_commonjs/cli/cli.cjs +33 -0
- package/dist_commonjs/cli/cli.d.ts +1 -0
- package/dist_commonjs/cli/cli.js.map +1 -0
- package/dist_commonjs/errors/BuildConfigError.cjs +8 -0
- package/dist_commonjs/errors/BuildConfigError.d.ts +3 -0
- package/dist_commonjs/errors/BuildConfigError.js.map +1 -0
- package/dist_commonjs/errors/BuildStepInputError.cjs +8 -0
- package/dist_commonjs/errors/BuildStepInputError.d.ts +3 -0
- package/dist_commonjs/errors/BuildStepInputError.js.map +1 -0
- package/dist_commonjs/errors/BuildStepOutputError.cjs +8 -0
- package/dist_commonjs/errors/BuildStepOutputError.d.ts +3 -0
- package/dist_commonjs/errors/BuildStepOutputError.js.map +1 -0
- package/dist_commonjs/errors/BuildStepRuntimeError.cjs +8 -0
- package/dist_commonjs/errors/BuildStepRuntimeError.d.ts +3 -0
- package/dist_commonjs/errors/BuildStepRuntimeError.js.map +1 -0
- package/dist_commonjs/errors/BuildWorkflowError.cjs +13 -0
- package/dist_commonjs/errors/BuildWorkflowError.d.ts +10 -0
- package/dist_commonjs/errors/BuildWorkflowError.js.map +1 -0
- package/dist_commonjs/errors/UserError.cjs +14 -0
- package/dist_commonjs/errors/UserError.d.ts +9 -0
- package/dist_commonjs/errors/UserError.js.map +1 -0
- package/dist_commonjs/index.cjs +8 -0
- package/dist_commonjs/index.d.ts +2 -0
- package/dist_commonjs/index.js.map +1 -0
- package/dist_commonjs/utils/expodash/uniq.cjs +9 -0
- package/dist_commonjs/utils/expodash/uniq.d.ts +1 -0
- package/dist_commonjs/utils/expodash/uniq.js.map +1 -0
- package/dist_commonjs/utils/nullthrows.cjs +11 -0
- package/dist_commonjs/utils/nullthrows.d.ts +1 -0
- package/dist_commonjs/utils/nullthrows.js.map +1 -0
- package/dist_commonjs/utils/shell/bin.cjs +11 -0
- package/dist_commonjs/utils/shell/bin.d.ts +1 -0
- package/dist_commonjs/utils/shell/bin.js.map +1 -0
- package/dist_commonjs/utils/shell/command.cjs +36 -0
- package/dist_commonjs/utils/shell/command.d.ts +6 -0
- package/dist_commonjs/utils/shell/command.js.map +1 -0
- package/dist_commonjs/utils/shell/spawn.cjs +25 -0
- package/dist_commonjs/utils/shell/spawn.d.ts +9 -0
- package/dist_commonjs/utils/shell/spawn.js.map +1 -0
- package/dist_commonjs/utils/shell/temporaryFiles.cjs +42 -0
- package/dist_commonjs/utils/shell/temporaryFiles.d.ts +4 -0
- package/dist_commonjs/utils/shell/temporaryFiles.js.map +1 -0
- package/dist_commonjs/utils/template.cjs +47 -0
- package/dist_commonjs/utils/template.d.ts +11 -0
- package/dist_commonjs/utils/template.js.map +1 -0
- package/dist_esm/BuildConfig.d.ts +25 -0
- package/dist_esm/BuildConfig.js +43 -0
- package/dist_esm/BuildConfig.js.map +1 -0
- package/dist_esm/BuildConfigParser.d.ts +14 -0
- package/dist_esm/BuildConfigParser.js +80 -0
- package/dist_esm/BuildConfigParser.js.map +1 -0
- package/dist_esm/BuildStep.d.ts +40 -0
- package/dist_esm/BuildStep.js +139 -0
- package/dist_esm/BuildStep.js.map +1 -0
- package/dist_esm/BuildStepContext.d.ts +13 -0
- package/dist_esm/BuildStepContext.js +25 -0
- package/dist_esm/BuildStepContext.js.map +1 -0
- package/dist_esm/BuildStepInput.d.ts +17 -0
- package/dist_esm/BuildStepInput.js +32 -0
- package/dist_esm/BuildStepInput.js.map +1 -0
- package/dist_esm/BuildStepOutput.d.ts +15 -0
- package/dist_esm/BuildStepOutput.js +25 -0
- package/dist_esm/BuildStepOutput.js.map +1 -0
- package/dist_esm/BuildWorkflow.d.ts +8 -0
- package/dist_esm/BuildWorkflow.js +11 -0
- package/dist_esm/BuildWorkflow.js.map +1 -0
- package/dist_esm/BuildWorkflowValidator.d.ts +8 -0
- package/dist_esm/BuildWorkflowValidator.js +72 -0
- package/dist_esm/BuildWorkflowValidator.js.map +1 -0
- package/dist_esm/cli/cli.d.ts +1 -0
- package/dist_esm/cli/cli.js +28 -0
- package/dist_esm/cli/cli.js.map +1 -0
- package/dist_esm/errors/BuildConfigError.d.ts +3 -0
- package/dist_esm/errors/BuildConfigError.js +4 -0
- package/dist_esm/errors/BuildConfigError.js.map +1 -0
- package/dist_esm/errors/BuildStepInputError.d.ts +3 -0
- package/dist_esm/errors/BuildStepInputError.js +4 -0
- package/dist_esm/errors/BuildStepInputError.js.map +1 -0
- package/dist_esm/errors/BuildStepOutputError.d.ts +3 -0
- package/dist_esm/errors/BuildStepOutputError.js +4 -0
- package/dist_esm/errors/BuildStepOutputError.js.map +1 -0
- package/dist_esm/errors/BuildStepRuntimeError.d.ts +3 -0
- package/dist_esm/errors/BuildStepRuntimeError.js +4 -0
- package/dist_esm/errors/BuildStepRuntimeError.js.map +1 -0
- package/dist_esm/errors/BuildWorkflowError.d.ts +10 -0
- package/dist_esm/errors/BuildWorkflowError.js +9 -0
- package/dist_esm/errors/BuildWorkflowError.js.map +1 -0
- package/dist_esm/errors/UserError.d.ts +9 -0
- package/dist_esm/errors/UserError.js +10 -0
- package/dist_esm/errors/UserError.js.map +1 -0
- package/dist_esm/index.d.ts +2 -0
- package/dist_esm/index.js +3 -0
- package/dist_esm/index.js.map +1 -0
- package/dist_esm/utils/expodash/uniq.d.ts +1 -0
- package/dist_esm/utils/expodash/uniq.js +5 -0
- package/dist_esm/utils/expodash/uniq.js.map +1 -0
- package/dist_esm/utils/nullthrows.d.ts +1 -0
- package/dist_esm/utils/nullthrows.js +7 -0
- package/dist_esm/utils/nullthrows.js.map +1 -0
- package/dist_esm/utils/shell/bin.d.ts +1 -0
- package/dist_esm/utils/shell/bin.js +5 -0
- package/dist_esm/utils/shell/bin.js.map +1 -0
- package/dist_esm/utils/shell/command.d.ts +6 -0
- package/dist_esm/utils/shell/command.js +28 -0
- package/dist_esm/utils/shell/command.js.map +1 -0
- package/dist_esm/utils/shell/spawn.d.ts +9 -0
- package/dist_esm/utils/shell/spawn.js +18 -0
- package/dist_esm/utils/shell/spawn.js.map +1 -0
- package/dist_esm/utils/shell/temporaryFiles.d.ts +4 -0
- package/dist_esm/utils/shell/temporaryFiles.js +33 -0
- package/dist_esm/utils/shell/temporaryFiles.js.map +1 -0
- package/dist_esm/utils/template.d.ts +11 -0
- package/dist_esm/utils/template.js +40 -0
- package/dist_esm/utils/template.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { BuildConfigError } from './errors/BuildConfigError.js';
|
|
2
|
+
import { BuildWorkflowError } from './errors/BuildWorkflowError.js';
|
|
3
|
+
import { findOutputPaths } from './utils/template.js';
|
|
4
|
+
export class BuildWorkflowValidator {
|
|
5
|
+
constructor(workflow) {
|
|
6
|
+
this.workflow = workflow;
|
|
7
|
+
}
|
|
8
|
+
validate() {
|
|
9
|
+
const errors = [];
|
|
10
|
+
errors.push(...this.validateUniqueStepIds());
|
|
11
|
+
errors.push(...this.validateInputs());
|
|
12
|
+
if (errors.length !== 0) {
|
|
13
|
+
throw new BuildWorkflowError('Build workflow is invalid', errors);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
validateUniqueStepIds() {
|
|
17
|
+
const stepIds = this.workflow.buildSteps.map(({ id }) => id);
|
|
18
|
+
const visitedStepIdsSet = new Set();
|
|
19
|
+
const duplicatedStepIdsSet = new Set();
|
|
20
|
+
for (const stepId of stepIds) {
|
|
21
|
+
if (visitedStepIdsSet.has(stepId)) {
|
|
22
|
+
duplicatedStepIdsSet.add(stepId);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
visitedStepIdsSet.add(stepId);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const duplicatedStepIds = [...duplicatedStepIdsSet];
|
|
29
|
+
if (duplicatedStepIds.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const error = new BuildConfigError(`Duplicated step IDs: ${duplicatedStepIds.map((i) => `"${i}"`).join(', ')}`);
|
|
34
|
+
return [error];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
validateInputs() {
|
|
38
|
+
var _a;
|
|
39
|
+
const errors = [];
|
|
40
|
+
const allStepIds = new Set(this.workflow.buildSteps.map((s) => s.id));
|
|
41
|
+
const stepByStepId = {};
|
|
42
|
+
for (const step of this.workflow.buildSteps) {
|
|
43
|
+
for (const input of (_a = step.inputs) !== null && _a !== void 0 ? _a : []) {
|
|
44
|
+
if (input.defaultValue === undefined) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const paths = findOutputPaths(input.defaultValue);
|
|
48
|
+
for (const { stepId, outputId } of paths) {
|
|
49
|
+
if (!(stepId in stepByStepId)) {
|
|
50
|
+
if (allStepIds.has(stepId)) {
|
|
51
|
+
const error = new BuildConfigError(`Input parameter "${input.id}" for step "${step.id}" uses an expression that references an output parameter from the future step "${stepId}".`);
|
|
52
|
+
errors.push(error);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
const error = new BuildConfigError(`Input parameter "${input.id}" for step "${step.id}" uses an expression that references an output parameter from a non-existent step "${stepId}".`);
|
|
56
|
+
errors.push(error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
if (!stepByStepId[stepId].hasOutputParameter(outputId)) {
|
|
61
|
+
const error = new BuildConfigError(`Input parameter "${input.id}" for step "${step.id}" uses an expression that references an undefined output parameter "${outputId}" from step "${stepId}".`);
|
|
62
|
+
errors.push(error);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
stepByStepId[step.id] = step;
|
|
68
|
+
}
|
|
69
|
+
return errors;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=BuildWorkflowValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildWorkflowValidator.js","sourceRoot":"","sources":["../src/BuildWorkflowValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { BuildStep } from './BuildStep.js';\nimport { BuildWorkflow } from './BuildWorkflow.js';\nimport { BuildConfigError } from './errors/BuildConfigError.js';\nimport { BuildWorkflowError } from './errors/BuildWorkflowError.js';\nimport { findOutputPaths } from './utils/template.js';\n\nexport class BuildWorkflowValidator {\n constructor(private readonly workflow: BuildWorkflow) {}\n\n public validate(): void {\n const errors: BuildConfigError[] = [];\n errors.push(...this.validateUniqueStepIds());\n errors.push(...this.validateInputs());\n if (errors.length !== 0) {\n throw new BuildWorkflowError('Build workflow is invalid', errors);\n }\n }\n\n private validateUniqueStepIds(): BuildConfigError[] {\n const stepIds = this.workflow.buildSteps.map(({ id }) => id);\n const visitedStepIdsSet = new Set<string>();\n const duplicatedStepIdsSet = new Set<string>();\n for (const stepId of stepIds) {\n if (visitedStepIdsSet.has(stepId)) {\n duplicatedStepIdsSet.add(stepId);\n } else {\n visitedStepIdsSet.add(stepId);\n }\n }\n const duplicatedStepIds = [...duplicatedStepIdsSet];\n if (duplicatedStepIds.length === 0) {\n return [];\n } else {\n const error = new BuildConfigError(\n `Duplicated step IDs: ${duplicatedStepIds.map((i) => `\"${i}\"`).join(', ')}`\n );\n return [error];\n }\n }\n\n private validateInputs(): BuildConfigError[] {\n const errors: BuildConfigError[] = [];\n\n const allStepIds = new Set(this.workflow.buildSteps.map((s) => s.id));\n const stepByStepId: Record<string, BuildStep> = {};\n for (const step of this.workflow.buildSteps) {\n for (const input of step.inputs ?? []) {\n if (input.defaultValue === undefined) {\n continue;\n }\n const paths = findOutputPaths(input.defaultValue);\n for (const { stepId, outputId } of paths) {\n if (!(stepId in stepByStepId)) {\n if (allStepIds.has(stepId)) {\n const error = new BuildConfigError(\n `Input parameter \"${input.id}\" for step \"${step.id}\" uses an expression that references an output parameter from the future step \"${stepId}\".`\n );\n errors.push(error);\n } else {\n const error = new BuildConfigError(\n `Input parameter \"${input.id}\" for step \"${step.id}\" uses an expression that references an output parameter from a non-existent step \"${stepId}\".`\n );\n errors.push(error);\n }\n } else {\n if (!stepByStepId[stepId].hasOutputParameter(outputId)) {\n const error = new BuildConfigError(\n `Input parameter \"${input.id}\" for step \"${step.id}\" uses an expression that references an undefined output parameter \"${outputId}\" from step \"${stepId}\".`\n );\n errors.push(error);\n }\n }\n }\n }\n stepByStepId[step.id] = step;\n }\n\n return errors;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { createLogger } from '@expo/logger';
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
+
import { BuildConfigParser } from '../BuildConfigParser.js';
|
|
5
|
+
import { BuildStepContext } from '../BuildStepContext.js';
|
|
6
|
+
const logger = createLogger({
|
|
7
|
+
name: 'steps-cli',
|
|
8
|
+
level: 'info',
|
|
9
|
+
});
|
|
10
|
+
async function runAsync(configPath, workingDirectory) {
|
|
11
|
+
const fakeBuildId = uuidv4();
|
|
12
|
+
const ctx = new BuildStepContext(fakeBuildId, logger, false, workingDirectory);
|
|
13
|
+
const parser = new BuildConfigParser(ctx, { configPath });
|
|
14
|
+
const workflow = await parser.parseAsync();
|
|
15
|
+
await workflow.executeAsync();
|
|
16
|
+
}
|
|
17
|
+
const relativeConfigPath = process.argv[2];
|
|
18
|
+
const relativeWorkingDirectoryPath = process.argv[3];
|
|
19
|
+
if (!relativeConfigPath && !relativeWorkingDirectoryPath) {
|
|
20
|
+
console.error('Usage: yarn cli config.yml path/to/working/directory');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const configPath = path.resolve(process.cwd(), relativeConfigPath);
|
|
24
|
+
const workingDirectory = path.resolve(process.cwd(), relativeWorkingDirectoryPath);
|
|
25
|
+
runAsync(configPath, workingDirectory).catch((err) => {
|
|
26
|
+
logger.error({ err }, 'Build failed');
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,MAAM,GAAG,YAAY,CAAC;IAC1B,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,MAAM;CACd,CAAC,CAAC;AAEH,KAAK,UAAU,QAAQ,CAAC,UAAkB,EAAE,gBAAwB;IAClE,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC3C,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3C,MAAM,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErD,IAAI,CAAC,kBAAkB,IAAI,CAAC,4BAA4B,EAAE;IACxD,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;AACnE,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC;AAEnF,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnD,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC","sourcesContent":["import path from 'path';\n\nimport { createLogger } from '@expo/logger';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BuildConfigParser } from '../BuildConfigParser.js';\nimport { BuildStepContext } from '../BuildStepContext.js';\n\nconst logger = createLogger({\n name: 'steps-cli',\n level: 'info',\n});\n\nasync function runAsync(configPath: string, workingDirectory: string): Promise<void> {\n const fakeBuildId = uuidv4();\n const ctx = new BuildStepContext(fakeBuildId, logger, false, workingDirectory);\n const parser = new BuildConfigParser(ctx, { configPath });\n const workflow = await parser.parseAsync();\n await workflow.executeAsync();\n}\n\nconst relativeConfigPath = process.argv[2];\nconst relativeWorkingDirectoryPath = process.argv[3];\n\nif (!relativeConfigPath && !relativeWorkingDirectoryPath) {\n console.error('Usage: yarn cli config.yml path/to/working/directory');\n process.exit(1);\n}\n\nconst configPath = path.resolve(process.cwd(), relativeConfigPath);\nconst workingDirectory = path.resolve(process.cwd(), relativeWorkingDirectoryPath);\n\nrunAsync(configPath, workingDirectory).catch((err) => {\n logger.error({ err }, 'Build failed');\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildConfigError.js","sourceRoot":"","sources":["../../src/errors/BuildConfigError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,gBAAiB,SAAQ,SAAS;CAAG","sourcesContent":["import { UserError } from './UserError.js';\n\nexport class BuildConfigError extends UserError {}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildStepInputError.js","sourceRoot":"","sources":["../../src/errors/BuildStepInputError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,mBAAoB,SAAQ,SAAS;CAAG","sourcesContent":["import { UserError } from './UserError.js';\n\nexport class BuildStepInputError extends UserError {}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildStepOutputError.js","sourceRoot":"","sources":["../../src/errors/BuildStepOutputError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,oBAAqB,SAAQ,SAAS;CAAG","sourcesContent":["import { UserError } from './UserError.js';\n\nexport class BuildStepOutputError extends UserError {}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildStepRuntimeError.js","sourceRoot":"","sources":["../../src/errors/BuildStepRuntimeError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,qBAAsB,SAAQ,SAAS;CAAG","sourcesContent":["import { UserError } from './UserError.js';\n\nexport class BuildStepRuntimeError extends UserError {}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BuildConfigError } from './BuildConfigError.js';
|
|
2
|
+
import { UserError } from './UserError.js';
|
|
3
|
+
export declare class BuildWorkflowError extends UserError {
|
|
4
|
+
readonly message: string;
|
|
5
|
+
readonly errors: BuildConfigError[];
|
|
6
|
+
constructor(message: string, errors: BuildConfigError[], extra?: {
|
|
7
|
+
metadata?: object;
|
|
8
|
+
cause?: Error;
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { UserError } from './UserError.js';
|
|
2
|
+
export class BuildWorkflowError extends UserError {
|
|
3
|
+
constructor(message, errors, extra) {
|
|
4
|
+
super(message, extra);
|
|
5
|
+
this.message = message;
|
|
6
|
+
this.errors = errors;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=BuildWorkflowError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildWorkflowError.js","sourceRoot":"","sources":["../../src/errors/BuildWorkflowError.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IAC/C,YAC2B,OAAe,EACxB,MAA0B,EAC1C,KAGC;QAED,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAPG,YAAO,GAAP,OAAO,CAAQ;QACxB,WAAM,GAAN,MAAM,CAAoB;IAO5C,CAAC;CACF","sourcesContent":["import { BuildConfigError } from './BuildConfigError.js';\nimport { UserError } from './UserError.js';\n\nexport class BuildWorkflowError extends UserError {\n constructor(\n public override readonly message: string,\n public readonly errors: BuildConfigError[],\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message, extra);\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export class UserError extends Error {
|
|
2
|
+
constructor(message, extra) {
|
|
3
|
+
var _a;
|
|
4
|
+
super(message);
|
|
5
|
+
this.message = message;
|
|
6
|
+
this.metadata = (_a = extra === null || extra === void 0 ? void 0 : extra.cause) !== null && _a !== void 0 ? _a : {};
|
|
7
|
+
this.cause = extra === null || extra === void 0 ? void 0 : extra.cause;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=UserError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserError.js","sourceRoot":"","sources":["../../src/errors/UserError.ts"],"names":[],"mappings":"AAAA,MAAM,OAAgB,SAAU,SAAQ,KAAK;IAI3C,YAC2B,OAAe,EACxC,KAGC;;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QANU,YAAO,GAAP,OAAO,CAAQ;QAOxC,IAAI,CAAC,QAAQ,GAAG,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,mCAAI,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,CAAC;IAC5B,CAAC;CACF","sourcesContent":["export abstract class UserError extends Error {\n public readonly cause?: Error;\n public readonly metadata: object;\n\n constructor(\n public override readonly message: string,\n extra?: {\n metadata?: object;\n cause?: Error;\n }\n ) {\n super(message);\n this.metadata = extra?.cause ?? {};\n this.cause = extra?.cause;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["export { BuildConfigParser } from './BuildConfigParser.js';\nexport { BuildStepContext } from './BuildStepContext.js';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function uniq<T = any>(items: T[]): T[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uniq.js","sourceRoot":"","sources":["../../../src/utils/expodash/uniq.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,IAAI,CAAU,KAAU;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;AAClB,CAAC","sourcesContent":["export function uniq<T = any>(items: T[]): T[] {\n const set = new Set(items);\n return [...set];\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function nullthrows<T>(value: T | null | undefined, message?: string): NonNullable<T>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export function nullthrows(value, message) {
|
|
2
|
+
if (value != null) {
|
|
3
|
+
return value;
|
|
4
|
+
}
|
|
5
|
+
throw new TypeError(message !== null && message !== void 0 ? message : `Expected value not to be null or undefined but got ${value}`);
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=nullthrows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullthrows.js","sourceRoot":"","sources":["../../src/utils/nullthrows.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAI,KAA2B,EAAE,OAAgB;IACzE,IAAI,KAAK,IAAI,IAAI,EAAE;QACjB,OAAO,KAAK,CAAC;KACd;IACD,MAAM,IAAI,SAAS,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,sDAAsD,KAAK,EAAE,CAAC,CAAC;AAChG,CAAC","sourcesContent":["export function nullthrows<T>(value: T | null | undefined, message?: string): NonNullable<T> {\n if (value != null) {\n return value;\n }\n throw new TypeError(message ?? `Expected value not to be null or undefined but got ${value}`);\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const BIN_PATH: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../../src/utils/shell/bin.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;AAE5B,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC","sourcesContent":["import path from 'path';\n\nimport { createContext } from 'this-file';\n\nconst ctx = createContext();\n\nexport const BIN_PATH = path.join(ctx.dirname, '../../../bin');\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
// stolen from https://circleci.com/docs/configuration-reference/
|
|
3
|
+
const DEFAULT_SHELL = '/bin/bash -eo pipefail';
|
|
4
|
+
const SHELL_BY_PLATFORM = {
|
|
5
|
+
darwin: '/bin/bash --login -eo pipefail',
|
|
6
|
+
};
|
|
7
|
+
export function getDefaultShell(platform = os.platform()) {
|
|
8
|
+
const platformSpecificShell = SHELL_BY_PLATFORM[platform];
|
|
9
|
+
if (platformSpecificShell) {
|
|
10
|
+
return platformSpecificShell;
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return DEFAULT_SHELL;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function getShellCommandAndArgs(shell, script) {
|
|
17
|
+
const splits = shell.split(' ');
|
|
18
|
+
const command = splits[0];
|
|
19
|
+
const args = [...splits.slice(1)];
|
|
20
|
+
if (script) {
|
|
21
|
+
args.push(script);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
command,
|
|
25
|
+
args,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../../src/utils/shell/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,iEAAiE;AACjE,MAAM,aAAa,GAAG,wBAAwB,CAAC;AAC/C,MAAM,iBAAiB,GAA6C;IAClE,MAAM,EAAE,gCAAgC;CACzC,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,WAA4B,EAAE,CAAC,QAAQ,EAAE;IACvE,MAAM,qBAAqB,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC1D,IAAI,qBAAqB,EAAE;QACzB,OAAO,qBAAqB,CAAC;KAC9B;SAAM;QACL,OAAO,aAAa,CAAC;KACtB;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,KAAa,EACb,MAAe;IAEf,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,MAAM,EAAE;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;KACnB;IACD,OAAO;QACL,OAAO;QACP,IAAI;KACL,CAAC;AACJ,CAAC","sourcesContent":["import os from 'os';\n\n// stolen from https://circleci.com/docs/configuration-reference/\nconst DEFAULT_SHELL = '/bin/bash -eo pipefail';\nconst SHELL_BY_PLATFORM: Partial<Record<NodeJS.Platform, string>> = {\n darwin: '/bin/bash --login -eo pipefail',\n};\n\nexport function getDefaultShell(platform: NodeJS.Platform = os.platform()): string {\n const platformSpecificShell = SHELL_BY_PLATFORM[platform];\n if (platformSpecificShell) {\n return platformSpecificShell;\n } else {\n return DEFAULT_SHELL;\n }\n}\n\nexport function getShellCommandAndArgs(\n shell: string,\n script?: string\n): { command: string; args?: string[] } {\n const splits = shell.split(' ');\n const command = splits[0];\n const args = [...splits.slice(1)];\n if (script) {\n args.push(script);\n }\n return {\n command,\n args,\n };\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { bunyan, PipeMode } from '@expo/logger';
|
|
2
|
+
import { SpawnResult, SpawnPromise, SpawnOptions as SpawnOptionsOriginal } from '@expo/spawn-async';
|
|
3
|
+
type SpawnOptions = SpawnOptionsOriginal & {
|
|
4
|
+
logger?: bunyan;
|
|
5
|
+
lineTransformer?: (line: string) => string | null;
|
|
6
|
+
mode?: PipeMode;
|
|
7
|
+
};
|
|
8
|
+
export declare function spawnAsync(command: string, args: string[], allOptions?: SpawnOptions): SpawnPromise<SpawnResult>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { pipeSpawnOutput } from '@expo/logger';
|
|
2
|
+
import spawnAsyncOriginal from '@expo/spawn-async';
|
|
3
|
+
// eslint-disable-next-line async-protect/async-suffix
|
|
4
|
+
export function spawnAsync(command, args, allOptions = {
|
|
5
|
+
stdio: 'inherit',
|
|
6
|
+
cwd: process.cwd(),
|
|
7
|
+
}) {
|
|
8
|
+
const { logger, ...options } = allOptions;
|
|
9
|
+
if (logger) {
|
|
10
|
+
options.stdio = 'pipe';
|
|
11
|
+
}
|
|
12
|
+
const promise = spawnAsyncOriginal(command, args, options);
|
|
13
|
+
if (logger && promise.child) {
|
|
14
|
+
pipeSpawnOutput(logger, promise.child, options);
|
|
15
|
+
}
|
|
16
|
+
return promise;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/utils/shell/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAoB,MAAM,cAAc,CAAC;AACjE,OAAO,kBAIN,MAAM,mBAAmB,CAAC;AAQ3B,sDAAsD;AACtD,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,IAAc,EACd,aAA2B;IACzB,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;CACnB;IAED,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,UAAU,CAAC;IAC1C,IAAI,MAAM,EAAE;QACV,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;KACxB;IACD,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3D,IAAI,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE;QAC3B,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;KACjD;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { pipeSpawnOutput, bunyan, PipeMode } from '@expo/logger';\nimport spawnAsyncOriginal, {\n SpawnResult,\n SpawnPromise,\n SpawnOptions as SpawnOptionsOriginal,\n} from '@expo/spawn-async';\n\ntype SpawnOptions = SpawnOptionsOriginal & {\n logger?: bunyan;\n lineTransformer?: (line: string) => string | null;\n mode?: PipeMode;\n};\n\n// eslint-disable-next-line async-protect/async-suffix\nexport function spawnAsync(\n command: string,\n args: string[],\n allOptions: SpawnOptions = {\n stdio: 'inherit',\n cwd: process.cwd(),\n }\n): SpawnPromise<SpawnResult> {\n const { logger, ...options } = allOptions;\n if (logger) {\n options.stdio = 'pipe';\n }\n const promise = spawnAsyncOriginal(command, args, options);\n if (logger && promise.child) {\n pipeSpawnOutput(logger, promise.child, options);\n }\n return promise;\n}\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BuildStepContext } from '../../BuildStepContext.js';
|
|
2
|
+
export declare function saveScriptToTemporaryFileAsync(ctx: BuildStepContext, stepId: string, scriptContents: string): Promise<string>;
|
|
3
|
+
export declare function createTemporaryOutputsDirectoryAsync(ctx: BuildStepContext, stepId: string): Promise<string>;
|
|
4
|
+
export declare function cleanUpTemporaryDirectoriesAsync(ctx: BuildStepContext, stepId: string): Promise<void>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
4
|
+
export async function saveScriptToTemporaryFileAsync(ctx, stepId, scriptContents) {
|
|
5
|
+
const scriptsDir = getTemporaryScriptsDirPath(ctx, stepId);
|
|
6
|
+
await fs.promises.mkdir(scriptsDir, { recursive: true });
|
|
7
|
+
const temporaryScriptPath = path.join(scriptsDir, `${uuidv4()}.sh`);
|
|
8
|
+
await fs.promises.writeFile(temporaryScriptPath, scriptContents);
|
|
9
|
+
return temporaryScriptPath;
|
|
10
|
+
}
|
|
11
|
+
export async function createTemporaryOutputsDirectoryAsync(ctx, stepId) {
|
|
12
|
+
const directory = getTemporaryOutputsDirPath(ctx, stepId);
|
|
13
|
+
await fs.promises.mkdir(directory, { recursive: true });
|
|
14
|
+
return directory;
|
|
15
|
+
}
|
|
16
|
+
export async function cleanUpTemporaryDirectoriesAsync(ctx, stepId) {
|
|
17
|
+
if (ctx.skipCleanup) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const stepTemporaryDirectory = getTemporaryStepDirPath(ctx, stepId);
|
|
21
|
+
await fs.promises.rm(stepTemporaryDirectory, { recursive: true });
|
|
22
|
+
ctx.logger.debug({ stepTemporaryDirectory }, 'Removed step temporary directory');
|
|
23
|
+
}
|
|
24
|
+
function getTemporaryStepDirPath(ctx, stepId) {
|
|
25
|
+
return path.join(ctx.baseWorkingDirectory, 'steps', stepId);
|
|
26
|
+
}
|
|
27
|
+
function getTemporaryScriptsDirPath(ctx, stepId) {
|
|
28
|
+
return path.join(getTemporaryStepDirPath(ctx, stepId), 'scripts');
|
|
29
|
+
}
|
|
30
|
+
function getTemporaryOutputsDirPath(ctx, stepId) {
|
|
31
|
+
return path.join(getTemporaryStepDirPath(ctx, stepId), 'outputs');
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=temporaryFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temporaryFiles.js","sourceRoot":"","sources":["../../../src/utils/shell/temporaryFiles.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAIpC,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAClD,GAAqB,EACrB,MAAc,EACd,cAAsB;IAEtB,MAAM,UAAU,GAAG,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,EAAE,KAAK,CAAC,CAAC;IACpE,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;IACjE,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,GAAqB,EACrB,MAAc;IAEd,MAAM,SAAS,GAAG,0BAA0B,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,GAAqB,EACrB,MAAc;IAEd,IAAI,GAAG,CAAC,WAAW,EAAE;QACnB,OAAO;KACR;IACD,MAAM,sBAAsB,GAAG,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpE,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,sBAAsB,EAAE,EAAE,kCAAkC,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,uBAAuB,CAAC,GAAqB,EAAE,MAAc;IACpE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,0BAA0B,CAAC,GAAqB,EAAE,MAAc;IACvE,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,0BAA0B,CAAC,GAAqB,EAAE,MAAc;IACvE,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;AACpE,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\n\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { BuildStepContext } from '../../BuildStepContext.js';\n\nexport async function saveScriptToTemporaryFileAsync(\n ctx: BuildStepContext,\n stepId: string,\n scriptContents: string\n): Promise<string> {\n const scriptsDir = getTemporaryScriptsDirPath(ctx, stepId);\n await fs.promises.mkdir(scriptsDir, { recursive: true });\n const temporaryScriptPath = path.join(scriptsDir, `${uuidv4()}.sh`);\n await fs.promises.writeFile(temporaryScriptPath, scriptContents);\n return temporaryScriptPath;\n}\n\nexport async function createTemporaryOutputsDirectoryAsync(\n ctx: BuildStepContext,\n stepId: string\n): Promise<string> {\n const directory = getTemporaryOutputsDirPath(ctx, stepId);\n await fs.promises.mkdir(directory, { recursive: true });\n return directory;\n}\n\nexport async function cleanUpTemporaryDirectoriesAsync(\n ctx: BuildStepContext,\n stepId: string\n): Promise<void> {\n if (ctx.skipCleanup) {\n return;\n }\n const stepTemporaryDirectory = getTemporaryStepDirPath(ctx, stepId);\n await fs.promises.rm(stepTemporaryDirectory, { recursive: true });\n ctx.logger.debug({ stepTemporaryDirectory }, 'Removed step temporary directory');\n}\n\nfunction getTemporaryStepDirPath(ctx: BuildStepContext, stepId: string): string {\n return path.join(ctx.baseWorkingDirectory, 'steps', stepId);\n}\n\nfunction getTemporaryScriptsDirPath(ctx: BuildStepContext, stepId: string): string {\n return path.join(getTemporaryStepDirPath(ctx, stepId), 'scripts');\n}\n\nfunction getTemporaryOutputsDirPath(ctx: BuildStepContext, stepId: string): string {\n return path.join(getTemporaryStepDirPath(ctx, stepId), 'outputs');\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const BUILD_STEP_INPUT_EXPRESSION_REGEXP: RegExp;
|
|
2
|
+
export declare const BUILD_STEP_OUTPUT_EXPRESSION_REGEXP: RegExp;
|
|
3
|
+
export declare function interpolateWithInputs(templateString: string, inputs: Record<string, string>): string;
|
|
4
|
+
export declare function interpolateWithOutputs(templateString: string, fn: (path: string) => string): string;
|
|
5
|
+
interface BuildOutputPath {
|
|
6
|
+
stepId: string;
|
|
7
|
+
outputId: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function findOutputPaths(templateString: string): BuildOutputPath[];
|
|
10
|
+
export declare function parseOutputPath(outputPath: string): BuildOutputPath;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { BuildConfigError } from '../errors/BuildConfigError.js';
|
|
2
|
+
import { nullthrows } from './nullthrows.js';
|
|
3
|
+
export const BUILD_STEP_INPUT_EXPRESSION_REGEXP = /\${\s*inputs\.([\S]+)\s*}/;
|
|
4
|
+
export const BUILD_STEP_OUTPUT_EXPRESSION_REGEXP = /\${\s*steps\.([\S]+)\s*}/;
|
|
5
|
+
export function interpolateWithInputs(templateString, inputs) {
|
|
6
|
+
return interpolate(templateString, BUILD_STEP_INPUT_EXPRESSION_REGEXP, inputs);
|
|
7
|
+
}
|
|
8
|
+
export function interpolateWithOutputs(templateString, fn) {
|
|
9
|
+
return interpolate(templateString, BUILD_STEP_OUTPUT_EXPRESSION_REGEXP, fn);
|
|
10
|
+
}
|
|
11
|
+
function interpolate(templateString, regex, varsOrFn) {
|
|
12
|
+
const matched = templateString.match(new RegExp(regex, 'g'));
|
|
13
|
+
if (!matched) {
|
|
14
|
+
return templateString;
|
|
15
|
+
}
|
|
16
|
+
let result = templateString;
|
|
17
|
+
for (const match of matched) {
|
|
18
|
+
const [, key] = nullthrows(match.match(regex));
|
|
19
|
+
const value = typeof varsOrFn === 'function' ? varsOrFn(key) : varsOrFn[key];
|
|
20
|
+
result = result.replace(match, value);
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
export function findOutputPaths(templateString) {
|
|
25
|
+
const result = [];
|
|
26
|
+
const matches = templateString.matchAll(new RegExp(BUILD_STEP_OUTPUT_EXPRESSION_REGEXP, 'g'));
|
|
27
|
+
for (const match of matches) {
|
|
28
|
+
result.push(parseOutputPath(match[1]));
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
export function parseOutputPath(outputPath) {
|
|
33
|
+
const splits = outputPath.split('.');
|
|
34
|
+
if (splits.length !== 2) {
|
|
35
|
+
throw new BuildConfigError(`Step output path must consist of two components joined with a dot, where first is the step ID, and second is the output name, e.g. "step3.output1". Passed: "${outputPath}"`);
|
|
36
|
+
}
|
|
37
|
+
const [stepId, outputId] = splits;
|
|
38
|
+
return { stepId, outputId };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,MAAM,kCAAkC,GAAG,2BAA2B,CAAC;AAC9E,MAAM,CAAC,MAAM,mCAAmC,GAAG,0BAA0B,CAAC;AAE9E,MAAM,UAAU,qBAAqB,CACnC,cAAsB,EACtB,MAA8B;IAE9B,OAAO,WAAW,CAAC,cAAc,EAAE,kCAAkC,EAAE,MAAM,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,cAAsB,EACtB,EAA4B;IAE5B,OAAO,WAAW,CAAC,cAAc,EAAE,mCAAmC,EAAE,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,WAAW,CAClB,cAAsB,EACtB,KAAa,EACb,QAA4D;IAE5D,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,cAAc,CAAC;KACvB;IACD,IAAI,MAAM,GAAG,cAAc,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;QAC3B,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7E,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;KACvC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAOD,MAAM,UAAU,eAAe,CAAC,cAAsB;IACpD,MAAM,MAAM,GAAsB,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC9F,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE;QAC3B,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,MAAM,IAAI,gBAAgB,CACxB,gKAAgK,UAAU,GAAG,CAC9K,CAAC;KACH;IACD,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC;IAClC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC9B,CAAC","sourcesContent":["import { BuildConfigError } from '../errors/BuildConfigError.js';\n\nimport { nullthrows } from './nullthrows.js';\n\nexport const BUILD_STEP_INPUT_EXPRESSION_REGEXP = /\\${\\s*inputs\\.([\\S]+)\\s*}/;\nexport const BUILD_STEP_OUTPUT_EXPRESSION_REGEXP = /\\${\\s*steps\\.([\\S]+)\\s*}/;\n\nexport function interpolateWithInputs(\n templateString: string,\n inputs: Record<string, string>\n): string {\n return interpolate(templateString, BUILD_STEP_INPUT_EXPRESSION_REGEXP, inputs);\n}\n\nexport function interpolateWithOutputs(\n templateString: string,\n fn: (path: string) => string\n): string {\n return interpolate(templateString, BUILD_STEP_OUTPUT_EXPRESSION_REGEXP, fn);\n}\n\nfunction interpolate(\n templateString: string,\n regex: RegExp,\n varsOrFn: Record<string, string> | ((key: string) => string)\n): string {\n const matched = templateString.match(new RegExp(regex, 'g'));\n if (!matched) {\n return templateString;\n }\n let result = templateString;\n for (const match of matched) {\n const [, key] = nullthrows(match.match(regex));\n const value = typeof varsOrFn === 'function' ? varsOrFn(key) : varsOrFn[key];\n result = result.replace(match, value);\n }\n return result;\n}\n\ninterface BuildOutputPath {\n stepId: string;\n outputId: string;\n}\n\nexport function findOutputPaths(templateString: string): BuildOutputPath[] {\n const result: BuildOutputPath[] = [];\n const matches = templateString.matchAll(new RegExp(BUILD_STEP_OUTPUT_EXPRESSION_REGEXP, 'g'));\n for (const match of matches) {\n result.push(parseOutputPath(match[1]));\n }\n return result;\n}\n\nexport function parseOutputPath(outputPath: string): BuildOutputPath {\n const splits = outputPath.split('.');\n if (splits.length !== 2) {\n throw new BuildConfigError(\n `Step output path must consist of two components joined with a dot, where first is the step ID, and second is the output name, e.g. \"step3.output1\". Passed: \"${outputPath}\"`\n );\n }\n const [stepId, outputId] = splits;\n return { stepId, outputId };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@expo/steps",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"main": "./dist_commonjs/index.cjs",
|
|
6
|
+
"types": "./dist_esm/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist_esm/index.d.ts",
|
|
10
|
+
"import": "./dist_esm/index.js",
|
|
11
|
+
"require": "./dist_commonjs/index.cjs"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin",
|
|
16
|
+
"dist_commonjs",
|
|
17
|
+
"dist_esm",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"start": "yarn watch",
|
|
22
|
+
"build": "./build.sh",
|
|
23
|
+
"watch": "chokidar --initial \"src/**/*.ts\" -c \"./build.sh\"",
|
|
24
|
+
"test": "node --experimental-vm-modules --no-warnings node_modules/.bin/jest -c=jest.config.cjs --no-cache",
|
|
25
|
+
"test:watch": "yarn test --watch",
|
|
26
|
+
"clean": "rm -rf node_modules dist_* coverage"
|
|
27
|
+
},
|
|
28
|
+
"author": "Expo <support@expo.io>",
|
|
29
|
+
"bugs": "https://github.com/expo/eas-build/issues",
|
|
30
|
+
"license": "BUSL-1.1",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@jest/globals": "^29.4.1",
|
|
33
|
+
"@types/jest": "^29.4.0",
|
|
34
|
+
"@types/node": "^18.11.18",
|
|
35
|
+
"bunyan": "^1.8.15",
|
|
36
|
+
"chokidar-cli": "^3.0.0",
|
|
37
|
+
"eslint-plugin-async-protect": "^3.0.0",
|
|
38
|
+
"jest": "^29.4.1",
|
|
39
|
+
"ts-jest": "^29.0.5",
|
|
40
|
+
"ts-mockito": "^2.6.1",
|
|
41
|
+
"typescript": "^4.9.5"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=14.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@expo/logger": "0.0.27",
|
|
48
|
+
"@expo/spawn-async": "^1.7.0",
|
|
49
|
+
"joi": "^17.7.0",
|
|
50
|
+
"this-file": "^2.0.3",
|
|
51
|
+
"uuid": "^9.0.0",
|
|
52
|
+
"yaml": "^2.2.1"
|
|
53
|
+
}
|
|
54
|
+
}
|