UNPKG

3.63 kBPlain TextView Raw
1import * as yargs from "yargs";
2import { loadDotenv } from "backfill-utils-dotenv";
3import { getCacheStorageProvider, ICacheStorage } from "backfill-cache";
4import { logger, setLogLevel } from "backfill-logger";
5import { createConfig, Config } from "backfill-config";
6import {
7 getRawBuildCommand,
8 createBuildCommand,
9 BuildCommand
10} from "./commandRunner";
11import { IHasher, Hasher } from "backfill-hasher";
12
13export { createDefaultConfig } from "backfill-config";
14
15import { initializeWatcher, closeWatcher } from "./audit";
16
17// Load environment variables
18loadDotenv();
19
20export async function backfill(
21 config: Config,
22 cacheStorage: ICacheStorage,
23 buildCommand: BuildCommand,
24 hasher: IHasher
25): Promise<void> {
26 const {
27 cacheStorageConfig,
28 outputFolder,
29 name,
30 mode,
31 logFolder,
32 producePerformanceLogs,
33 validateOutput
34 } = config;
35
36 logger.setName(name);
37 logger.setMode(mode);
38 logger.setCacheProvider(cacheStorageConfig.provider);
39
40 const createPackageHash = async () => await hasher.createPackageHash();
41 const fetch = async (hash: string) =>
42 await cacheStorage.fetch(hash, outputFolder);
43 const run = async () => {
44 try {
45 await buildCommand();
46 } catch (err) {
47 throw new Error(`Command failed with the following error:\n\n${err}`);
48 }
49 };
50 const put = async (hash: string) => {
51 try {
52 await cacheStorage.put(hash, outputFolder);
53 } catch (err) {
54 logger.error(
55 `Failed to persist the cache with the following error:\n\n${err}`
56 );
57 }
58 };
59
60 switch (mode) {
61 case "READ_WRITE": {
62 const hash = await createPackageHash();
63
64 if (!(await fetch(hash))) {
65 await run();
66 await put(hash);
67 }
68
69 break;
70 }
71 case "READ_ONLY": {
72 const hash = await createPackageHash();
73
74 if (!(await fetch(hash))) {
75 await run();
76 }
77
78 break;
79 }
80 case "WRITE_ONLY": {
81 const hash = await createPackageHash();
82
83 await run();
84 await put(hash);
85
86 break;
87 }
88 case "PASS": {
89 await run();
90 break;
91 }
92 }
93
94 if (validateOutput) {
95 const hashOfOutput = await hasher.hashOfOutput();
96 logger.setHashOfOutput(hashOfOutput);
97 }
98
99 if (producePerformanceLogs) {
100 await logger.toFile(logFolder);
101 }
102}
103
104export async function main(): Promise<void> {
105 try {
106 const config = createConfig();
107 const {
108 cacheStorageConfig,
109 clearOutputFolder,
110 hashGlobs,
111 internalCacheFolder,
112 logFolder,
113 logLevel,
114 outputFolder,
115 packageRoot
116 } = config;
117
118 if (logLevel) {
119 setLogLevel(logLevel);
120 }
121
122 const helpString = "Backfills unchanged packages.";
123
124 const argv = yargs
125 .strict()
126 .usage(helpString)
127 .alias("h", "help")
128 .version(false)
129 .option("audit", {
130 description: "Compare files changed with those cached",
131 type: "boolean"
132 }).argv;
133
134 const buildCommand = createBuildCommand(
135 argv["_"],
136 clearOutputFolder,
137 outputFolder
138 );
139
140 const cacheStorage = getCacheStorageProvider(
141 cacheStorageConfig,
142 internalCacheFolder
143 );
144
145 const hasher = new Hasher(
146 { packageRoot, outputFolder },
147 getRawBuildCommand()
148 );
149
150 if (argv["audit"]) {
151 initializeWatcher(
152 packageRoot,
153 internalCacheFolder,
154 logFolder,
155 outputFolder,
156 hashGlobs
157 );
158 }
159
160 await backfill(config, cacheStorage, buildCommand, hasher);
161
162 if (argv["audit"]) {
163 await closeWatcher();
164 }
165 } catch (err) {
166 logger.error(err);
167 process.exit(1);
168 }
169}