2021-02-04 19:15:23 +01:00
|
|
|
const { promises: fs } = require('fs');
|
|
|
|
const path = require('path');
|
2023-04-06 20:37:55 +02:00
|
|
|
const childProcess = require('child_process');
|
|
|
|
const { mergeWith, cloneDeep, capitalize } = require('lodash');
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-05-26 06:48:23 +02:00
|
|
|
const baseManifest = process.env.ENABLE_MV3
|
|
|
|
? require('../../app/manifest/v3/_base.json')
|
|
|
|
: require('../../app/manifest/v2/_base.json');
|
2023-04-25 16:32:51 +02:00
|
|
|
const { loadBuildTypesConfig } = require('../lib/build-type');
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2023-04-06 20:37:55 +02:00
|
|
|
const { TASKS, ENVIRONMENT } = require('./constants');
|
2021-02-04 19:15:23 +01:00
|
|
|
const { createTask, composeSeries } = require('./task');
|
2023-04-06 20:37:55 +02:00
|
|
|
const { getEnvironment } = require('./utils');
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
module.exports = createManifestTasks;
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-10-06 19:44:48 +02:00
|
|
|
function createManifestTasks({
|
|
|
|
browserPlatforms,
|
|
|
|
browserVersionMap,
|
|
|
|
buildType,
|
2023-04-06 20:37:55 +02:00
|
|
|
applyLavaMoat,
|
|
|
|
shouldIncludeSnow,
|
|
|
|
entryTask,
|
2021-10-06 19:44:48 +02:00
|
|
|
}) {
|
2020-03-09 01:55:02 +01:00
|
|
|
// merge base manifest with per-platform manifests
|
|
|
|
const prepPlatforms = async () => {
|
2020-11-03 00:41:28 +01:00
|
|
|
return Promise.all(
|
|
|
|
browserPlatforms.map(async (platform) => {
|
|
|
|
const platformModifications = await readJson(
|
|
|
|
path.join(
|
|
|
|
__dirname,
|
|
|
|
'..',
|
|
|
|
'..',
|
|
|
|
'app',
|
2022-05-26 06:48:23 +02:00
|
|
|
process.env.ENABLE_MV3 ? 'manifest/v3' : 'manifest/v2',
|
2020-11-03 00:41:28 +01:00
|
|
|
`${platform}.json`,
|
|
|
|
),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2021-12-07 23:31:01 +01:00
|
|
|
const result = mergeWith(
|
2021-05-10 23:16:03 +02:00
|
|
|
cloneDeep(baseManifest),
|
|
|
|
platformModifications,
|
2021-10-06 19:44:48 +02:00
|
|
|
browserVersionMap[platform],
|
2021-11-11 00:03:59 +01:00
|
|
|
await getBuildModifications(buildType, platform),
|
2021-12-07 23:31:01 +01:00
|
|
|
customArrayMerge,
|
2021-05-10 23:16:03 +02:00
|
|
|
);
|
2023-04-06 20:37:55 +02:00
|
|
|
|
|
|
|
modifyNameAndDescForNonProd(result);
|
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
const dir = path.join('.', 'dist', platform);
|
|
|
|
await fs.mkdir(dir, { recursive: true });
|
|
|
|
await writeJson(result, path.join(dir, 'manifest.json'));
|
2020-11-03 00:41:28 +01:00
|
|
|
}),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
|
|
|
};
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-31 05:12:28 +02:00
|
|
|
// dev: add perms
|
2020-03-09 01:55:02 +01:00
|
|
|
const envDev = createTaskForModifyManifestForEnvironment((manifest) => {
|
2021-02-04 19:15:23 +01:00
|
|
|
manifest.permissions = [...manifest.permissions, 'webRequestBlocking'];
|
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-03-31 05:12:28 +02:00
|
|
|
// testDev: add perms
|
2020-03-09 01:55:02 +01:00
|
|
|
const envTestDev = createTaskForModifyManifestForEnvironment((manifest) => {
|
2020-11-03 00:41:28 +01:00
|
|
|
manifest.permissions = [
|
|
|
|
...manifest.permissions,
|
|
|
|
'webRequestBlocking',
|
|
|
|
'http://localhost/*',
|
2021-02-04 19:15:23 +01:00
|
|
|
];
|
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
|
|
|
|
// test: add permissions
|
|
|
|
const envTest = createTaskForModifyManifestForEnvironment((manifest) => {
|
2020-11-03 00:41:28 +01:00
|
|
|
manifest.permissions = [
|
|
|
|
...manifest.permissions,
|
|
|
|
'webRequestBlocking',
|
|
|
|
'http://localhost/*',
|
2021-02-04 19:15:23 +01:00
|
|
|
];
|
|
|
|
});
|
2020-03-09 01:55:02 +01:00
|
|
|
|
|
|
|
// high level manifest tasks
|
2022-06-21 22:07:05 +02:00
|
|
|
const dev = createTask(
|
|
|
|
TASKS.MANIFEST_DEV,
|
|
|
|
composeSeries(prepPlatforms, envDev),
|
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
const testDev = createTask(
|
2022-06-21 22:07:05 +02:00
|
|
|
TASKS.MANIFEST_TEST_DEV,
|
2020-11-03 00:41:28 +01:00
|
|
|
composeSeries(prepPlatforms, envTestDev),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2020-11-03 00:41:28 +01:00
|
|
|
const test = createTask(
|
2022-06-21 22:07:05 +02:00
|
|
|
TASKS.MANIFEST_TEST,
|
2020-11-03 00:41:28 +01:00
|
|
|
composeSeries(prepPlatforms, envTest),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2022-06-21 22:07:05 +02:00
|
|
|
const prod = createTask(TASKS.MANIFEST_PROD, prepPlatforms);
|
2020-03-09 01:55:02 +01:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
return { prod, dev, testDev, test };
|
2020-03-09 01:55:02 +01:00
|
|
|
|
|
|
|
// helper for modifying each platform's manifest.json in place
|
2020-11-03 00:41:28 +01:00
|
|
|
function createTaskForModifyManifestForEnvironment(transformFn) {
|
2020-03-09 01:55:02 +01:00
|
|
|
return () => {
|
2020-11-03 00:41:28 +01:00
|
|
|
return Promise.all(
|
|
|
|
browserPlatforms.map(async (platform) => {
|
2021-02-04 19:15:23 +01:00
|
|
|
const manifestPath = path.join(
|
|
|
|
'.',
|
|
|
|
'dist',
|
|
|
|
platform,
|
|
|
|
'manifest.json',
|
|
|
|
);
|
|
|
|
const manifest = await readJson(manifestPath);
|
|
|
|
transformFn(manifest);
|
2023-04-06 20:37:55 +02:00
|
|
|
|
2021-02-04 19:15:23 +01:00
|
|
|
await writeJson(manifest, manifestPath);
|
2020-11-03 00:41:28 +01:00
|
|
|
}),
|
2021-02-04 19:15:23 +01:00
|
|
|
);
|
|
|
|
};
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
2021-12-07 23:31:01 +01:00
|
|
|
|
2023-04-06 20:37:55 +02:00
|
|
|
// For non-production builds only, modify the extension's name and description
|
|
|
|
function modifyNameAndDescForNonProd(manifest) {
|
|
|
|
const environment = getEnvironment({ buildTarget: entryTask });
|
|
|
|
|
|
|
|
if (environment === ENVIRONMENT.PRODUCTION) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const mv3Str = process.env.ENABLE_MV3 ? ' MV3' : '';
|
|
|
|
const lavamoatStr = applyLavaMoat ? ' lavamoat' : '';
|
|
|
|
const snowStr = shouldIncludeSnow ? ' snow' : '';
|
|
|
|
|
|
|
|
// Get the first 8 characters of the git revision id
|
|
|
|
const gitRevisionStr = childProcess
|
|
|
|
.execSync('git rev-parse HEAD')
|
|
|
|
.toString()
|
|
|
|
.trim()
|
|
|
|
.substring(0, 8);
|
|
|
|
|
|
|
|
manifest.name = `MetaMask ${capitalize(
|
|
|
|
buildType,
|
|
|
|
)}${mv3Str}${lavamoatStr}${snowStr}`;
|
|
|
|
|
|
|
|
manifest.description = `${environment} build from git id: ${gitRevisionStr}`;
|
|
|
|
}
|
|
|
|
|
2021-12-07 23:31:01 +01:00
|
|
|
// helper for merging obj value
|
|
|
|
function customArrayMerge(objValue, srcValue) {
|
|
|
|
if (Array.isArray(objValue)) {
|
|
|
|
return [...new Set([...objValue, ...srcValue])];
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
}
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// helper for reading and deserializing json from fs
|
2020-11-03 00:41:28 +01:00
|
|
|
async function readJson(file) {
|
2021-02-04 19:15:23 +01:00
|
|
|
return JSON.parse(await fs.readFile(file, 'utf8'));
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// helper for serializing and writing json to fs
|
2020-11-03 00:41:28 +01:00
|
|
|
async function writeJson(obj, file) {
|
2021-02-04 19:15:23 +01:00
|
|
|
return fs.writeFile(file, JSON.stringify(obj, null, 2));
|
2020-03-09 01:55:02 +01:00
|
|
|
}
|
2021-09-08 22:08:23 +02:00
|
|
|
|
2021-11-11 00:03:59 +01:00
|
|
|
/**
|
|
|
|
* Get manifest modifications for the given build type, including modifications specific to the
|
|
|
|
* given platform.
|
|
|
|
*
|
2023-04-25 16:32:51 +02:00
|
|
|
* @param {string} buildType - The build type.
|
2021-11-11 00:03:59 +01:00
|
|
|
* @param {string} platform - The platform (i.e. the browser).
|
2023-04-25 16:32:51 +02:00
|
|
|
* @returns {object} The build modifications for the given build type and platform.
|
2021-11-11 00:03:59 +01:00
|
|
|
*/
|
|
|
|
async function getBuildModifications(buildType, platform) {
|
2023-04-25 16:32:51 +02:00
|
|
|
const buildConfig = loadBuildTypesConfig();
|
|
|
|
if (!(buildType in buildConfig.buildTypes)) {
|
2021-11-11 00:03:59 +01:00
|
|
|
throw new Error(`Invalid build type: ${buildType}`);
|
2023-04-25 16:32:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const overridesPath = buildConfig.buildTypes[buildType].manifestOverrides;
|
2023-05-05 18:40:43 +02:00
|
|
|
if (!overridesPath) {
|
2021-11-11 00:03:59 +01:00
|
|
|
return {};
|
Rationalize build system arguments (#12047)
This rationalizes how arguments are passed to and parsed by the build system. To accomplish this, everything that isn't an environment variable from `.metamaskrc` or our CI environment is now passed as an argument on the command line.
Of such arguments, the `entryTask` is still expected as a positional argument in the first position (i.e. `process.argv[2]`), but everything else must be passed as a named argument. We use `minimist` to parse the arguments, and set defaults to preserve existing behavior.
Arguments are parsed in a new function, `parseArgv`, in `development/build/index.js`. They are assigned to environment variables where convenient, and otherwise returned from `parseArgv` to be passed to other functions invoked in the same file.
This change is motivated by our previous inconsistent handling of arguments to the build system, which will grow increasingly problematic as the build system grows in complexity. (Which it will very shortly, as we introduce Flask builds.)
Miscellaneous changes:
- Adds a build system readme at `development/build/README.md`
- Removes the `beta` package script. Now, we can instead call: `yarn dist --build-type beta`
- Fixes the casing of some log messages and reorders some parameters in the build system
2021-09-09 21:44:57 +02:00
|
|
|
}
|
2021-11-11 00:03:59 +01:00
|
|
|
|
|
|
|
const builtTypeManifestDirectoryPath = path.resolve(
|
2023-04-25 16:32:51 +02:00
|
|
|
process.cwd(),
|
|
|
|
overridesPath,
|
2021-11-11 00:03:59 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
const baseBuildTypeModificationsPath = path.join(
|
|
|
|
builtTypeManifestDirectoryPath,
|
|
|
|
'_base.json',
|
|
|
|
);
|
|
|
|
const buildModifications = await readJson(baseBuildTypeModificationsPath);
|
|
|
|
|
|
|
|
const platformBuildTypeModificationsPath = path.join(
|
|
|
|
builtTypeManifestDirectoryPath,
|
|
|
|
`${platform}.json`,
|
|
|
|
);
|
|
|
|
try {
|
|
|
|
const platformBuildTypeModifications = await readJson(
|
|
|
|
platformBuildTypeModificationsPath,
|
|
|
|
);
|
|
|
|
Object.assign(buildModifications, platformBuildTypeModifications);
|
|
|
|
} catch (error) {
|
|
|
|
// Suppress 'ENOENT' error because it indicates there are no platform-specific manifest
|
|
|
|
// modifications for this build type.
|
|
|
|
if (error.code !== 'ENOENT') {
|
|
|
|
throw error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-06 19:44:48 +02:00
|
|
|
return buildModifications;
|
2021-09-08 22:08:23 +02:00
|
|
|
}
|