mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Remove Fibers from meteor-tools:
- Adapt forkJoin and other files functions to correctly be awaited.
This commit is contained in:
@@ -1725,7 +1725,7 @@ var maybeUpdateRelease = async function (options) {
|
||||
await projectContext.prepareProjectForBuild();
|
||||
});
|
||||
|
||||
projectContext.writeReleaseFileAndDevBundleLink(releaseName);
|
||||
await projectContext.writeReleaseFileAndDevBundleLink(releaseName);
|
||||
|
||||
projectContext.packageMapDelta.displayOnConsole({
|
||||
title: ("Changes to your project's package version selections from " +
|
||||
@@ -2734,7 +2734,7 @@ main.registerCommand({
|
||||
throw Error("missing tool for " + osArch);
|
||||
}
|
||||
|
||||
tmpTropo.linkToLatestMeteor(files.pathJoin(
|
||||
await tmpTropo.linkToLatestMeteor(files.pathJoin(
|
||||
tmpTropo.packagePath(toolPackage, toolVersion, true),
|
||||
toolRecord.path,
|
||||
'meteor'));
|
||||
|
||||
@@ -928,6 +928,7 @@ makeGlobalAsyncLocalStorage().run({}, async function () {
|
||||
appReleaseFile = new projectContextModule.ReleaseFile({
|
||||
projectDir: appDir
|
||||
});
|
||||
await appReleaseFile.init();
|
||||
// This is what happens if the file exists and is empty. This really
|
||||
// shouldn't happen unless the user did it manually.
|
||||
if (appReleaseFile.noReleaseSpecified()) {
|
||||
|
||||
@@ -487,7 +487,7 @@ function pathIsDirectory(path: string) {
|
||||
// If options.ignore is present, it should be a list of regexps. Any
|
||||
// file whose basename matches one of the regexps, before
|
||||
// transformation, will be skipped.
|
||||
export function cp_r(from: string, to: string, options: {
|
||||
export async function cp_r(from: string, to: string, options: {
|
||||
preserveSymlinks?: boolean;
|
||||
ignore?: RegExp[];
|
||||
transformFilename?: (f: string) => string;
|
||||
@@ -531,7 +531,7 @@ export function cp_r(from: string, to: string, options: {
|
||||
mkdir_p(pathDirname(to));
|
||||
|
||||
if (stat.isSymbolicLink()) {
|
||||
symlinkWithOverwrite(readlink(from), to);
|
||||
await symlinkWithOverwrite(readlink(from), to);
|
||||
|
||||
} else if (options.transformContents) {
|
||||
writeFile(to, options.transformContents(
|
||||
@@ -557,7 +557,7 @@ export function cp_r(from: string, to: string, options: {
|
||||
// create a symlink, overwriting the target link, file, or directory
|
||||
// if it exists
|
||||
export const symlinkWithOverwrite =
|
||||
Profile("files.symlinkWithOverwrite", function symlinkWithOverwrite(
|
||||
Profile("files.symlinkWithOverwrite", async function symlinkWithOverwrite(
|
||||
source: string,
|
||||
target: string,
|
||||
) {
|
||||
@@ -586,7 +586,7 @@ Profile("files.symlinkWithOverwrite", function symlinkWithOverwrite(
|
||||
return;
|
||||
}
|
||||
// overwrite existing link, file, or directory
|
||||
rm_recursive(target);
|
||||
await rm_recursive(target);
|
||||
symlink(...args);
|
||||
} else {
|
||||
throw e;
|
||||
@@ -746,10 +746,10 @@ export function changeTempDirStatus(dir: string, status: boolean) {
|
||||
|
||||
if (! process.env.METEOR_SAVE_TMPDIRS) {
|
||||
cleanup.onExit(function () {
|
||||
Object.entries(tempDirs).filter(([_, isTmp]) => !!isTmp).map(([dir]) => dir).forEach(dir => {
|
||||
return Object.entries(tempDirs).filter(([_, isTmp]) => !!isTmp).map(([dir]) => dir).map(async dir => {
|
||||
delete tempDirs[dir];
|
||||
try {
|
||||
rm_recursive(dir);
|
||||
await rm_recursive(dir);
|
||||
} catch (err) {
|
||||
// Don't crash and print a stack trace because we failed to delete
|
||||
// a temp directory. This happens sometimes on Windows and seems
|
||||
@@ -768,7 +768,7 @@ type TarOptions = {
|
||||
// into a destination directory. destPath should not exist yet, and
|
||||
// the archive should contain a single top-level directory, which will
|
||||
// be renamed atomically to destPath.
|
||||
export function extractTarGz(
|
||||
export async function extractTarGz(
|
||||
buffer: Buffer,
|
||||
destPath: string,
|
||||
options: TarOptions = {},
|
||||
@@ -784,9 +784,7 @@ export function extractTarGz(
|
||||
const startTime = +new Date;
|
||||
|
||||
// standardize only one way of extracting, as native ones can be tricky
|
||||
const promise = tryExtractWithNpmTar(buffer, tempDir, options)
|
||||
|
||||
promise.await();
|
||||
await tryExtractWithNpmTar(buffer, tempDir, options);
|
||||
|
||||
// succeed!
|
||||
const topLevelOfArchive = readdir(tempDir)
|
||||
@@ -800,8 +798,8 @@ export function extractTarGz(
|
||||
}
|
||||
|
||||
const extractDir = pathJoin(tempDir, topLevelOfArchive[0]);
|
||||
rename(extractDir, destPath);
|
||||
rm_recursive(tempDir);
|
||||
await rename(extractDir, destPath);
|
||||
await rm_recursive(tempDir);
|
||||
|
||||
if (options.verbose) {
|
||||
console.log("Finished extracting in", Date.now() - startTime, "ms");
|
||||
@@ -978,7 +976,7 @@ Profile("files.renameDirAlmostAtomically", async (fromDir: string, toDir: string
|
||||
});
|
||||
|
||||
export const writeFileAtomically =
|
||||
Profile("files.writeFileAtomically", function (filename: string, contents: string | Buffer) {
|
||||
Profile("files.writeFileAtomically", async function (filename: string, contents: string | Buffer) {
|
||||
const parentDir = pathDirname(filename);
|
||||
mkdir_p(parentDir);
|
||||
|
||||
@@ -988,19 +986,19 @@ Profile("files.writeFileAtomically", function (filename: string, contents: strin
|
||||
);
|
||||
|
||||
writeFile(tmpFile, contents);
|
||||
rename(tmpFile, filename);
|
||||
await rename(tmpFile, filename);
|
||||
});
|
||||
|
||||
// Like fs.symlinkSync, but creates a temporary link and renames it over the
|
||||
// file; this means it works even if the file already exists.
|
||||
// Do not use this function on Windows, it won't work.
|
||||
export function symlinkOverSync(linkText: string, file: string) {
|
||||
export async function symlinkOverSync(linkText: string, file: string) {
|
||||
file = pathResolve(file);
|
||||
const tmpSymlink = pathJoin(
|
||||
pathDirname(file),
|
||||
"." + pathBasename(file) + ".tmp" + utils.randomToken());
|
||||
symlink(linkText, tmpSymlink);
|
||||
rename(tmpSymlink, file);
|
||||
await rename(tmpSymlink, file);
|
||||
}
|
||||
|
||||
// Return the result of evaluating `code` using
|
||||
@@ -1375,7 +1373,7 @@ export function _getLocationFromScriptLinkToMeteorScript(script: string | Buffer
|
||||
return convertToPosixPath(scriptLocation, ! isAbsolute);
|
||||
}
|
||||
|
||||
export function linkToMeteorScript(
|
||||
export async function linkToMeteorScript(
|
||||
scriptLocation: string,
|
||||
linkLocation: string,
|
||||
platform: string,
|
||||
@@ -1390,7 +1388,7 @@ export function linkToMeteorScript(
|
||||
writeFile(linkLocation, script, { encoding: "ascii" });
|
||||
} else {
|
||||
// Symlink meteor tool
|
||||
symlinkOverSync(scriptLocation, linkLocation);
|
||||
await symlinkOverSync(scriptLocation, linkLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1615,11 +1613,11 @@ export const rename = isWindowsLikeFilesystem() ? function (from: string, to: st
|
||||
}
|
||||
}
|
||||
attempt();
|
||||
}).catch((error: any) => {
|
||||
}).catch(async (error: any) => {
|
||||
if (error.code === 'EPERM' ||
|
||||
error.code === 'EACCESS') {
|
||||
cp_r(from, to, { preserveSymlinks: true });
|
||||
rm_recursive(from);
|
||||
await rm_recursive(from);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
const absPath = files.pathJoin(this.buildPath, relPath);
|
||||
|
||||
if (symlink) {
|
||||
symlinkWithOverwrite(symlink, absPath);
|
||||
await symlinkWithOverwrite(symlink, absPath);
|
||||
} else {
|
||||
hash = hash || sha1(getData());
|
||||
|
||||
@@ -604,7 +604,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
return this._copyDirectory(options);
|
||||
}
|
||||
|
||||
_copyDirectory({
|
||||
async _copyDirectory({
|
||||
from, to,
|
||||
ignore,
|
||||
specificFiles,
|
||||
@@ -642,12 +642,12 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
|
||||
const rootDir = realpath(from);
|
||||
|
||||
const walk = (absFrom, relTo) => {
|
||||
const walk = async (absFrom, relTo) => {
|
||||
if (symlink && ! (relTo in this.usedAsFile)) {
|
||||
this._ensureDirectory(files.pathDirname(relTo));
|
||||
const absTo = files.pathResolve(this.buildPath, relTo);
|
||||
if (this.previousCreatedSymlinks[absFrom] !== relTo) {
|
||||
symlinkWithOverwrite(absFrom, absTo);
|
||||
await symlinkWithOverwrite(absFrom, absTo);
|
||||
}
|
||||
this.usedAsFile[relTo] = false;
|
||||
this.createdSymlinks[absFrom] = relTo;
|
||||
@@ -656,12 +656,12 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
|
||||
this._ensureDirectory(relTo);
|
||||
|
||||
optimisticReaddir(absFrom).forEach(item => {
|
||||
for (const item of optimisticReaddir(absFrom)) {
|
||||
let thisAbsFrom = files.pathResolve(absFrom, item);
|
||||
const thisRelTo = files.pathJoin(relTo, item);
|
||||
|
||||
if (specificPaths && !(thisRelTo in specificPaths)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Returns files.realpath(thisAbsFrom), if it is external to
|
||||
@@ -684,7 +684,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
}
|
||||
|
||||
const isExternal =
|
||||
files.pathRelative(rootDir, real).startsWith("..");
|
||||
files.pathRelative(rootDir, real).startsWith("..");
|
||||
|
||||
// Now cachedExternalPath is either a string or false.
|
||||
return cachedExternalPath = isExternal && real;
|
||||
@@ -709,7 +709,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
|
||||
if (! fileStatus) {
|
||||
// If the file did not exist, skip it.
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let itemForMatch = item;
|
||||
@@ -720,22 +720,22 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
|
||||
// skip excluded files
|
||||
if (ignore.some(pattern => itemForMatch.match(pattern))) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof filter === "function" &&
|
||||
! filter(thisAbsFrom, isDirectory)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (npmDiscards instanceof NpmDiscards &&
|
||||
npmDiscards.shouldDiscard(thisAbsFrom, isDirectory)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isDirectory) {
|
||||
walk(thisAbsFrom, thisRelTo);
|
||||
return;
|
||||
await walk(thisAbsFrom, thisRelTo);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fileStatus.isSymbolicLink()) {
|
||||
@@ -743,16 +743,16 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
// portable than absolute links, so getExternalPath() is
|
||||
// preferred if it returns a path.
|
||||
const linkSource = getExternalPath() ||
|
||||
files.readlink(thisAbsFrom);
|
||||
files.readlink(thisAbsFrom);
|
||||
|
||||
const linkTarget =
|
||||
files.pathResolve(this.buildPath, thisRelTo);
|
||||
files.pathResolve(this.buildPath, thisRelTo);
|
||||
|
||||
if (symlinkIfPossible(linkSource, linkTarget)) {
|
||||
if (await symlinkIfPossible(linkSource, linkTarget)) {
|
||||
// A symlink counts as a file, as far as "can you put
|
||||
// something under it" goes.
|
||||
this.usedAsFile[thisRelTo] = true;
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -767,28 +767,28 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
const content = optimisticReadFile(thisAbsFrom);
|
||||
|
||||
files.writeFile(
|
||||
files.pathResolve(this.buildPath, thisRelTo),
|
||||
// The reason we call files.writeFile here instead of
|
||||
// files.copyFile is so that we can read the file using
|
||||
// optimisticReadFile instead of files.createReadStream.
|
||||
content,
|
||||
// Logic borrowed from files.copyFile: "Create the file as
|
||||
// readable and writable by everyone, and executable by everyone
|
||||
// if the original file is executably by owner. (This mode will be
|
||||
// modified by umask.) We don't copy the mode *directly* because
|
||||
// this function is used by 'meteor create' which is copying from
|
||||
// the read-only tools tree into a writable app."
|
||||
{ mode: (fileStatus.mode & 0o100) ? 0o777 : 0o666 },
|
||||
files.pathResolve(this.buildPath, thisRelTo),
|
||||
// The reason we call files.writeFile here instead of
|
||||
// files.copyFile is so that we can read the file using
|
||||
// optimisticReadFile instead of files.createReadStream.
|
||||
content,
|
||||
// Logic borrowed from files.copyFile: "Create the file as
|
||||
// readable and writable by everyone, and executable by everyone
|
||||
// if the original file is executably by owner. (This mode will be
|
||||
// modified by umask.) We don't copy the mode *directly* because
|
||||
// this function is used by 'meteor create' which is copying from
|
||||
// the read-only tools tree into a writable app."
|
||||
{ mode: (fileStatus.mode & 0o100) ? 0o777 : 0o666 },
|
||||
);
|
||||
}
|
||||
|
||||
this.writtenHashes[thisRelTo] = hash;
|
||||
this.usedAsFile[thisRelTo] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
walk(rootDir, to);
|
||||
await walk(rootDir, to);
|
||||
}
|
||||
|
||||
// Returns a new Builder-compatible object that works just like a
|
||||
@@ -801,7 +801,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
//
|
||||
// TODO(benjamn) This nonsense should be ripped out by any means
|
||||
// necessary... whenever someone has the time.
|
||||
enter(relPath) {
|
||||
async enter(relPath) {
|
||||
const subBuilder = {};
|
||||
const relPathWithSep = relPath + files.pathSep;
|
||||
const methods = [
|
||||
@@ -814,8 +814,8 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
"enter",
|
||||
];
|
||||
|
||||
methods.forEach(method => {
|
||||
subBuilder[method] = (...args) => {
|
||||
for (const method of methods) {
|
||||
subBuilder[method] = async (...args) => {
|
||||
if (method === "copyDirectory" ||
|
||||
method === "copyNodeModulesDirectory") {
|
||||
// The copy methods take their relative paths via options.to.
|
||||
@@ -825,7 +825,7 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
args[0] = files.pathJoin(relPath, args[0]);
|
||||
}
|
||||
|
||||
let ret = this[method](...args);
|
||||
let ret = await this[method](...args);
|
||||
|
||||
if (method === "generateFilename") {
|
||||
// fix up the returned path to be relative to the
|
||||
@@ -835,14 +835,14 @@ Previous builder: ${previousBuilder.outputPath}, this builder: ${outputPath}`
|
||||
}
|
||||
if (ret.substr(0, relPathWithSep.length) !== relPathWithSep) {
|
||||
throw new Error("generateFilename returned path outside of " +
|
||||
"sub-bundle?");
|
||||
"sub-bundle?");
|
||||
}
|
||||
ret = ret.substr(relPathWithSep.length);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// Methods that don't have to fix up arguments or return values, because
|
||||
// they are implemented purely in terms of other methods which do.
|
||||
@@ -943,9 +943,9 @@ async function atomicallyRewriteFile(path, data, options) {
|
||||
}
|
||||
}
|
||||
|
||||
function symlinkIfPossible(source, target) {
|
||||
async function symlinkIfPossible(source, target) {
|
||||
try {
|
||||
symlinkWithOverwrite(source, target);
|
||||
await symlinkWithOverwrite(source, target);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
|
||||
@@ -2503,7 +2503,7 @@ class JsImage {
|
||||
// them, and 'meteor run' symlinks them. If these contain
|
||||
// arch-specific code then the target will end up having an
|
||||
// appropriately specific arch.
|
||||
_.each(nodeModulesDirectories, function (nmd) {
|
||||
for (const nmd of Object.values(nodeModulesDirectories)) {
|
||||
assert.strictEqual(typeof nmd.preferredBundlePath, "string");
|
||||
|
||||
// Skip calculating isPortable in 'meteor run' since the
|
||||
@@ -2522,15 +2522,15 @@ class JsImage {
|
||||
};
|
||||
|
||||
const prodPackagePredicate =
|
||||
// This condition essentially means we don't strip devDependencies
|
||||
// when running tests, which is important for use cases like the one
|
||||
// described in #7953. Note that devDependencies can still be used
|
||||
// when buildMode === "development" because the app has access to
|
||||
// the original node_modules.
|
||||
(buildMode === "production" ||
|
||||
buildMode === "development") &&
|
||||
nmd.local && // Only filter local node_modules directories.
|
||||
nmd.getProdPackagePredicate();
|
||||
// This condition essentially means we don't strip devDependencies
|
||||
// when running tests, which is important for use cases like the one
|
||||
// described in #7953. Note that devDependencies can still be used
|
||||
// when buildMode === "development" because the app has access to
|
||||
// the original node_modules.
|
||||
(buildMode === "production" ||
|
||||
buildMode === "development") &&
|
||||
nmd.local && // Only filter local node_modules directories.
|
||||
nmd.getProdPackagePredicate();
|
||||
|
||||
if (prodPackagePredicate) {
|
||||
// When copying a local node_modules directory, ignore any npm
|
||||
@@ -2546,9 +2546,9 @@ class JsImage {
|
||||
copyOptions.filter = prodPackagePredicate;
|
||||
}
|
||||
|
||||
builder.copyNodeModulesDirectory(copyOptions);
|
||||
await builder.copyNodeModulesDirectory(copyOptions);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// This JSON file will be read by npm-rebuild.js, which is executed to
|
||||
// trigger rebuilds for all non-portable npm packages.
|
||||
|
||||
@@ -97,7 +97,7 @@ const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function (
|
||||
|
||||
if (cacheFilePath) {
|
||||
Promise.resolve().then(
|
||||
() => writeFileAtomically(cacheFilePath, result),
|
||||
async () => await writeFileAtomically(cacheFilePath, result),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1163,7 +1163,7 @@ Object.assign(Isopack.prototype, {
|
||||
var pluginDir = builder.generateFilename(
|
||||
'plugin.' + colonConverter.convert(name) + '.' + plugin.arch,
|
||||
{ directory: true });
|
||||
var pluginBuild = await plugin.write(builder.enter(pluginDir));
|
||||
var pluginBuild = await plugin.write(await builder.enter(pluginDir));
|
||||
var pluginEntry = {
|
||||
name: name,
|
||||
arch: plugin.arch,
|
||||
|
||||
@@ -580,7 +580,7 @@ export async function bundleAndDeploy(options) {
|
||||
|
||||
if (options.isCacheBuildEnabled) {
|
||||
Console.info('Saving build in cache (--cache-build)...');
|
||||
options.projectContext.saveBuildCache({
|
||||
await options.projectContext.saveBuildCache({
|
||||
buildDir,
|
||||
bundlePath,
|
||||
gitCommitHash
|
||||
|
||||
@@ -39,10 +39,10 @@ var generateBlankReadme = function () {
|
||||
};
|
||||
|
||||
// Save a readme file to a temporary path.
|
||||
var saveReadmeToTmp = function (readmeInfo) {
|
||||
var saveReadmeToTmp = async function (readmeInfo) {
|
||||
var tempReadmeDir = files.mkdtemp('readme');
|
||||
var readmePath = files.pathJoin(tempReadmeDir, "Readme.md");
|
||||
files.writeFileAtomically(readmePath, readmeInfo.contents);
|
||||
await files.writeFileAtomically(readmePath, readmeInfo.contents);
|
||||
return readmePath;
|
||||
};
|
||||
|
||||
|
||||
@@ -618,10 +618,10 @@ Object.assign(exports.Tropohouse.prototype, {
|
||||
return files.readLinkToMeteorScript(linkPath, self.platform);
|
||||
},
|
||||
|
||||
linkToLatestMeteor: function (scriptLocation) {
|
||||
linkToLatestMeteor: async function (scriptLocation) {
|
||||
var self = this;
|
||||
var linkPath = files.pathJoin(self.root, 'meteor');
|
||||
files.linkToMeteorScript(scriptLocation, linkPath, self.platform);
|
||||
await files.linkToMeteorScript(scriptLocation, linkPath, self.platform);
|
||||
},
|
||||
|
||||
_getPlatform: function () {
|
||||
|
||||
@@ -391,9 +391,9 @@ Object.assign(ProjectContext.prototype, {
|
||||
var self = this;
|
||||
buildmessage.assertInCapture();
|
||||
|
||||
await buildmessage.enterJob('reading project metadata', function () {
|
||||
await buildmessage.enterJob('reading project metadata', async function () {
|
||||
// Ensure this is actually a project directory.
|
||||
self._ensureProjectDir();
|
||||
await self._ensureProjectDir();
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
@@ -402,6 +402,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
projectDir: self.projectDir,
|
||||
catalog: self._officialCatalog,
|
||||
});
|
||||
await self.releaseFile.init();
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
@@ -424,6 +425,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
self.cordovaPluginsFile = new exports.CordovaPluginsFile({
|
||||
projectDir: self.projectDir
|
||||
});
|
||||
await self.cordovaPluginsFile.init();
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
@@ -431,11 +433,13 @@ Object.assign(ProjectContext.prototype, {
|
||||
self.platformList = new exports.PlatformList({
|
||||
projectDir: self.projectDir
|
||||
});
|
||||
await self.platformList._init();
|
||||
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
// Read .meteor/.id, creating it if necessary.
|
||||
self._ensureAppIdentifier();
|
||||
await self._ensureAppIdentifier();
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
@@ -460,12 +464,12 @@ Object.assign(ProjectContext.prototype, {
|
||||
|
||||
// Write the new release to .meteor/release and create a
|
||||
// .meteor/dev_bundle symlink to the corresponding dev_bundle.
|
||||
writeReleaseFileAndDevBundleLink(releaseName) {
|
||||
async writeReleaseFileAndDevBundleLink(releaseName) {
|
||||
assert.strictEqual(files.inCheckout(), false);
|
||||
this.releaseFile.write(releaseName);
|
||||
await this.releaseFile.write(releaseName);
|
||||
},
|
||||
|
||||
_ensureProjectDir: function () {
|
||||
_ensureProjectDir: async function () {
|
||||
var self = this;
|
||||
files.mkdir_p(files.pathJoin(self.projectDir, '.meteor'));
|
||||
|
||||
@@ -473,13 +477,13 @@ Object.assign(ProjectContext.prototype, {
|
||||
// so let's make sure it exists!
|
||||
var constraintFilePath = files.pathJoin(self.projectDir, '.meteor', 'packages');
|
||||
if (! files.exists(constraintFilePath)) {
|
||||
files.writeFileAtomically(constraintFilePath, '');
|
||||
await files.writeFileAtomically(constraintFilePath, '');
|
||||
}
|
||||
|
||||
// Let's also make sure we have a minimal gitignore.
|
||||
var gitignorePath = files.pathJoin(self.projectDir, '.meteor', '.gitignore');
|
||||
if (! files.exists(gitignorePath)) {
|
||||
files.writeFileAtomically(gitignorePath, 'local\n');
|
||||
await files.writeFileAtomically(gitignorePath, 'local\n');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -526,7 +530,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
return self.isopackCache.getLintingMessagesForLocalPackages();
|
||||
},
|
||||
|
||||
_ensureAppIdentifier: function () {
|
||||
_ensureAppIdentifier: async function () {
|
||||
var self = this;
|
||||
var identifierFile = files.pathJoin(self.projectDir, '.meteor', '.id');
|
||||
|
||||
@@ -551,7 +555,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
"# - ensuring you don't accidentally deploy one app on top of another\n" +
|
||||
"# - providing package authors with aggregated statistics\n" +
|
||||
"\n");
|
||||
files.writeFileAtomically(identifierFile, comment + appId + '\n');
|
||||
await files.writeFileAtomically(identifierFile, comment + appId + '\n');
|
||||
}
|
||||
|
||||
self.appIdentifier = appId;
|
||||
@@ -660,7 +664,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
|
||||
await self.packageMapDelta.init();
|
||||
|
||||
self._saveResolverResultCache();
|
||||
await self._saveResolverResultCache();
|
||||
|
||||
self._completedStage = STAGE.RESOLVE_CONSTRAINTS;
|
||||
});
|
||||
@@ -684,8 +688,8 @@ Object.assign(ProjectContext.prototype, {
|
||||
return this._resolverResultCache;
|
||||
},
|
||||
|
||||
_saveResolverResultCache() {
|
||||
files.writeFileAtomically(
|
||||
async _saveResolverResultCache() {
|
||||
await files.writeFileAtomically(
|
||||
files.pathJoin(
|
||||
this.projectLocalDir,
|
||||
"resolver-result-cache.json"
|
||||
@@ -705,8 +709,8 @@ Object.assign(ProjectContext.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
saveBuildCache(buildCache) {
|
||||
files.writeFileAtomically(
|
||||
async saveBuildCache(buildCache) {
|
||||
await files.writeFileAtomically(
|
||||
files.pathJoin(
|
||||
this.projectLocalDir,
|
||||
"build-cache.json"
|
||||
@@ -968,12 +972,12 @@ Object.assign(ProjectContext.prototype, {
|
||||
self._completedStage = STAGE.BUILD_LOCAL_PACKAGES;
|
||||
}),
|
||||
|
||||
_saveChangedMetadata: Profile('_saveChangedMetadata', function () {
|
||||
_saveChangedMetadata: Profile('_saveChangedMetadata', async function () {
|
||||
var self = this;
|
||||
|
||||
// Save any changes to .meteor/packages.
|
||||
if (! self._neverWriteProjectConstraintsFile)
|
||||
self.projectConstraintsFile.writeIfModified();
|
||||
await self.projectConstraintsFile.writeIfModified();
|
||||
|
||||
// Write .meteor/versions if the command always wants to (create/update),
|
||||
// or if the release of the app matches the release of the process.
|
||||
@@ -983,7 +987,7 @@ Object.assign(ProjectContext.prototype, {
|
||||
(! release.current.isCheckout() &&
|
||||
release.current.name === self.releaseFile.fullReleaseName))) {
|
||||
|
||||
self.packageMapFile.write(self.packageMap);
|
||||
await self.packageMapFile.write(self.packageMap);
|
||||
}
|
||||
|
||||
self._completedStage = STAGE.SAVE_CHANGED_METADATA;
|
||||
@@ -1098,12 +1102,12 @@ Object.assign(exports.ProjectConstraintsFile.prototype, {
|
||||
});
|
||||
},
|
||||
|
||||
writeIfModified: function () {
|
||||
writeIfModified: async function () {
|
||||
var self = this;
|
||||
self._modified && self._write();
|
||||
self._modified && (await self._write());
|
||||
},
|
||||
|
||||
_write: function () {
|
||||
_write: async function () {
|
||||
var self = this;
|
||||
var lines = _.map(self._constraintLines, function (lineRecord) {
|
||||
// Don't write packages that were not loaded from .meteor/packages
|
||||
@@ -1119,7 +1123,7 @@ Object.assign(exports.ProjectConstraintsFile.prototype, {
|
||||
lineParts.push(lineRecord.trailingSpaceAndComment, '\n');
|
||||
return lineParts.join('');
|
||||
});
|
||||
files.writeFileAtomically(self.filename, lines.join(''));
|
||||
await files.writeFileAtomically(self.filename, lines.join(''));
|
||||
var messages = buildmessage.capture(
|
||||
{ title: 're-reading .meteor/packages' },
|
||||
function () {
|
||||
@@ -1299,7 +1303,7 @@ Object.assign(exports.PackageMapFile.prototype, {
|
||||
return _.clone(self._versions);
|
||||
},
|
||||
|
||||
write: function (packageMap) {
|
||||
write: async function (packageMap) {
|
||||
var self = this;
|
||||
var newVersions = packageMap.toVersionMap();
|
||||
|
||||
@@ -1316,7 +1320,7 @@ Object.assign(exports.PackageMapFile.prototype, {
|
||||
lines.push(packageName + "@" + self._versions[packageName] + "\n");
|
||||
});
|
||||
var fileContents = Buffer.from(lines.join(''));
|
||||
files.writeFileAtomically(self.filename, fileContents);
|
||||
await files.writeFileAtomically(self.filename, fileContents);
|
||||
|
||||
// Replace our watchSet with one for the new contents of the file.
|
||||
var hash = watch.sha1(fileContents);
|
||||
@@ -1335,15 +1339,17 @@ exports.PlatformList = function (options) {
|
||||
self.filename = files.pathJoin(options.projectDir, '.meteor', 'platforms');
|
||||
self.watchSet = null;
|
||||
self._platforms = null;
|
||||
|
||||
self._readFile();
|
||||
};
|
||||
|
||||
// These platforms are always present and can be neither added or removed
|
||||
exports.PlatformList.DEFAULT_PLATFORMS = ['browser', 'server'];
|
||||
|
||||
Object.assign(exports.PlatformList.prototype, {
|
||||
_readFile: function () {
|
||||
_init: async function() {
|
||||
const self = this;
|
||||
await self._readFile();
|
||||
},
|
||||
_readFile: async function () {
|
||||
var self = this;
|
||||
|
||||
// Reset the WatchSet.
|
||||
@@ -1363,7 +1369,7 @@ Object.assign(exports.PlatformList.prototype, {
|
||||
// Write the platforms to disk (automatically adding DEFAULT_PLATFORMS and
|
||||
// sorting), which automatically calls this function recursively to
|
||||
// re-reads them.
|
||||
self.write(platforms);
|
||||
await self.write(platforms);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1372,14 +1378,14 @@ Object.assign(exports.PlatformList.prototype, {
|
||||
|
||||
// Replaces the current platform file with the given list and resets this
|
||||
// object (and its WatchSet) to track the new value.
|
||||
write: function (platforms) {
|
||||
write: async function (platforms) {
|
||||
var self = this;
|
||||
self._platforms = null;
|
||||
platforms = _.uniq(
|
||||
platforms.concat(exports.PlatformList.DEFAULT_PLATFORMS));
|
||||
platforms.sort();
|
||||
files.writeFileAtomically(self.filename, platforms.join('\n') + '\n');
|
||||
self._readFile();
|
||||
await files.writeFileAtomically(self.filename, platforms.join('\n') + '\n');
|
||||
await self._readFile();
|
||||
},
|
||||
|
||||
getPlatforms: function () {
|
||||
@@ -1426,11 +1432,13 @@ exports.CordovaPluginsFile = function (options) {
|
||||
self.watchSet = null;
|
||||
// Map from plugin name to version.
|
||||
self._plugins = null;
|
||||
|
||||
self._readFile();
|
||||
};
|
||||
|
||||
Object.assign(exports.CordovaPluginsFile.prototype, {
|
||||
init: async function() {
|
||||
const self = this;
|
||||
await self._readFile();
|
||||
},
|
||||
_readFile: function () {
|
||||
var self = this;
|
||||
buildmessage.assertInCapture();
|
||||
@@ -1476,18 +1484,18 @@ Object.assign(exports.CordovaPluginsFile.prototype, {
|
||||
return _.clone(self._plugins);
|
||||
},
|
||||
|
||||
write: function (plugins) {
|
||||
write: async function (plugins) {
|
||||
var self = this;
|
||||
var pluginNames = Object.keys(plugins);
|
||||
pluginNames.sort();
|
||||
var lines = _.map(pluginNames, function (pluginName) {
|
||||
return pluginName + '@' + plugins[pluginName] + '\n';
|
||||
});
|
||||
files.writeFileAtomically(self.filename, lines.join(''));
|
||||
var messages = buildmessage.capture(
|
||||
await files.writeFileAtomically(self.filename, lines.join(''));
|
||||
var messages = await buildmessage.capture(
|
||||
{ title: 're-reading .meteor/cordova-plugins' },
|
||||
function () {
|
||||
self._readFile();
|
||||
async function () {
|
||||
await self._readFile();
|
||||
});
|
||||
// We shouldn't choke on something we just wrote!
|
||||
if (messages.hasMessages())
|
||||
@@ -1516,10 +1524,13 @@ exports.ReleaseFile = function (options) {
|
||||
// Just the track.
|
||||
self.releaseTrack = null;
|
||||
self.releaseVersion = null;
|
||||
self._readFile();
|
||||
};
|
||||
|
||||
Object.assign(exports.ReleaseFile.prototype, {
|
||||
init: async function() {
|
||||
const self = this;
|
||||
await self._readFile();
|
||||
},
|
||||
fileMissing: function () {
|
||||
var self = this;
|
||||
return self.unnormalizedReleaseName === null;
|
||||
@@ -1538,7 +1549,7 @@ Object.assign(exports.ReleaseFile.prototype, {
|
||||
|| self.isCheckout());
|
||||
},
|
||||
|
||||
_readFile: function () {
|
||||
_readFile: async function () {
|
||||
var self = this;
|
||||
|
||||
// Start a new watchSet, in case we just overwrote this.
|
||||
@@ -1566,7 +1577,7 @@ Object.assign(exports.ReleaseFile.prototype, {
|
||||
self.releaseTrack = parts[0];
|
||||
self.releaseVersion = parts[1];
|
||||
|
||||
self.ensureDevBundleLink();
|
||||
await self.ensureDevBundleLink();
|
||||
},
|
||||
|
||||
// Returns an absolute path to the dev_bundle appropriate for the
|
||||
@@ -1598,7 +1609,7 @@ Object.assign(exports.ReleaseFile.prototype, {
|
||||
},
|
||||
|
||||
// Make a symlink from .meteor/local/dev_bundle to the actual dev_bundle.
|
||||
ensureDevBundleLink() {
|
||||
async ensureDevBundleLink() {
|
||||
import { makeLink, readLink } from "./cli/dev-bundle-links.js";
|
||||
|
||||
const dotMeteorDir = files.pathDirname(this.filename);
|
||||
@@ -1608,7 +1619,7 @@ Object.assign(exports.ReleaseFile.prototype, {
|
||||
if (this.isCheckout()) {
|
||||
// Only create .meteor/local/dev_bundle if .meteor/release refers to
|
||||
// an actual release, and remove it otherwise.
|
||||
files.rm_recursive(devBundleLink);
|
||||
await files.rm_recursive(devBundleLink);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1643,10 +1654,10 @@ Object.assign(exports.ReleaseFile.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
write: function (releaseName) {
|
||||
write: async function (releaseName) {
|
||||
var self = this;
|
||||
files.writeFileAtomically(self.filename, releaseName + '\n');
|
||||
self._readFile();
|
||||
await files.writeFileAtomically(self.filename, releaseName + '\n');
|
||||
await self._readFile();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
// A simple interface to register functions to be called when the process exits.
|
||||
|
||||
import { noYieldsAllowed } from "../utils/fiber-helpers.js";
|
||||
|
||||
const exitHandlers = [];
|
||||
|
||||
export function onExit(func) {
|
||||
exitHandlers.push(func);
|
||||
}
|
||||
|
||||
function runHandlers() {
|
||||
noYieldsAllowed(() => {
|
||||
// Empty and execute all queued exit handlers.
|
||||
exitHandlers.splice(0).forEach((f) => {
|
||||
f();
|
||||
});
|
||||
});
|
||||
async function runHandlers() {
|
||||
await Promise.all(exitHandlers.splice(0).map(f => f()));
|
||||
}
|
||||
|
||||
process.on('exit', runHandlers);
|
||||
['SIGINT', 'SIGHUP', 'SIGTERM'].forEach((sig) => {
|
||||
process.once(sig, () => {
|
||||
runHandlers();
|
||||
process.once(sig, async () => {
|
||||
await runHandlers();
|
||||
process.kill(process.pid, sig);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -583,7 +583,7 @@ var mergeMessagesIntoCurrentJob = function (innerMessages) {
|
||||
};
|
||||
|
||||
// Like _.each, but runs each operation in a separate job
|
||||
var forkJoin = function (options, iterable, fn) {
|
||||
var forkJoin = async function (options, iterable, fn) {
|
||||
if (!_.isFunction(fn)) {
|
||||
fn = iterable;
|
||||
iterable = options;
|
||||
@@ -602,44 +602,38 @@ var forkJoin = function (options, iterable, fn) {
|
||||
|
||||
const parallel = (options.parallel !== undefined) ? options.parallel : true;
|
||||
|
||||
return enterJobAsync(options).then(() => {
|
||||
const errors = [];
|
||||
let results = _.map(iterable, (...args) => {
|
||||
const promise = enterJobAsync({
|
||||
await enterJobAsync(options);
|
||||
|
||||
const errors = [];
|
||||
let results = [];
|
||||
const mappedPromises = iterable.map(async (...args) => {
|
||||
try {
|
||||
await enterJobAsync({
|
||||
title: (options.title || "") + " child"
|
||||
}).then(() => fn(...args))
|
||||
// Collect any errors thrown (and later re-throw the first one),
|
||||
// but don't stop processing remaining jobs.
|
||||
.catch(error => (errors.push(error), null));
|
||||
|
||||
if (parallel) {
|
||||
// If the jobs are intended to run in parallel, return each
|
||||
// promise without awaiting it, so that Promise.all can wait for
|
||||
// them all to be fulfilled.
|
||||
return promise;
|
||||
}
|
||||
|
||||
// By awaiting the promise during each iteration, we effectively
|
||||
// serialize the execution of the jobs.
|
||||
return promise.await();
|
||||
});
|
||||
|
||||
if (parallel) {
|
||||
// If the jobs ran in parallel, then results is an array of Promise
|
||||
// objects that still need to be resolved.
|
||||
results = Promise.all(results).await();
|
||||
});
|
||||
await fn(...args);
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
// If any errors were thrown, re-throw the first one. Note that this
|
||||
// allows jobs to complete successfully (and have whatever
|
||||
// side-effects they should have) after the first error is thrown,
|
||||
// though the final results will not be returned below.
|
||||
throw errors[0];
|
||||
if (parallel) {
|
||||
results = await Promise.all(mappedPromises);
|
||||
} else {
|
||||
for (const mappedPromise of mappedPromises) {
|
||||
results.push(await mappedPromise);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}).await();
|
||||
if (errors.length > 0) {
|
||||
// If any errors were thrown, re-throw the first one. Note that this
|
||||
// allows jobs to complete successfully (and have whatever
|
||||
// side-effects they should have) after the first error is thrown,
|
||||
// though the final results will not be returned below.
|
||||
throw errors[0];
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user