Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
e => `--exclude=${path.join(relativePathFromRoot, e)}`,
);
await execa('git', [
'apply',
// According to git documentation, `--binary` flag is turned on by
// default. However it's necessary when running `git apply --check` to
// actually accept binary files, maybe a bug in git?
'--binary',
'--check',
tmpPatchFile,
...excludes,
'-p2',
'--3way',
`--directory=${relativePathFromRoot}`,
]);
logger.info('Applying diff...');
} catch (error) {
const errorLines: Array = error.stderr.split('\n');
filesThatDontExist = [
...errorLines
.filter(x => x.includes('does not exist in index'))
.map(x => x.replace(/^error: (.*): does not exist in index$/, '$1')),
].filter(Boolean);
filesThatFailedToApply = errorLines
.filter(x => x.includes('patch does not apply'))
.map(x => x.replace(/^error: (.*): patch does not apply$/, '$1'))
.filter(Boolean);
logger.info('Applying diff...');
logger.warn(
`Excluding files that exist in the template, but not in your project:\n${filesThatDontExist
async function installTemplateDevDependencies(
templatePath: string,
root: string,
) {
// devDependencies.json is a special file that lists additional develop dependencies
// that are required by this template
const devDependenciesJsonPath = path.resolve(
templatePath,
'devDependencies.json',
);
logger.info('Adding develop dependencies for the project...');
if (!fs.existsSync(devDependenciesJsonPath)) {
logger.info('No additional develop dependencies.');
return;
}
let dependencies: any;
try {
dependencies = require(devDependenciesJsonPath);
} catch (err) {
throw new Error(
`Could not parse the template's devDependencies.json: ${err.message}`,
);
}
const dependenciesToInstall = Object.keys(dependencies).map(
depName => `${depName}@${dependencies[depName]}`,
);
await PackageManager.installDev(dependenciesToInstall, {root});
output: typeof outputBundle = outputBundle,
) {
const config = await loadMetroConfig(ctx, {
maxWorkers: args.maxWorkers,
resetCache: args.resetCache,
config: args.config,
});
if (config.resolver.platforms.indexOf(args.platform) === -1) {
logger.error(
`Invalid platform ${
args.platform ? `"${chalk.bold(args.platform)}" ` : ''
}selected.`,
);
logger.info(
`Available platforms are: ${config.resolver.platforms
.map(x => `"${chalk.bold(x)}"`)
.join(
', ',
)}. If you are trying to bundle for an out-of-tree platform, it may not be installed.`,
);
throw new Error('Bundling failed');
}
// This is used by a bazillion of npm modules we don't control so we don't
// have other choice than defining it as an env variable here.
process.env.NODE_ENV = args.dev ? 'development' : 'production';
let sourceMapUrl = args.sourcemapOutput;
if (sourceMapUrl && !args.sourcemapUseAbsolutePath) {
async function installTemplateDevDependencies(
templatePath: string,
root: string,
) {
// devDependencies.json is a special file that lists additional develop dependencies
// that are required by this template
const devDependenciesJsonPath = path.resolve(
templatePath,
'devDependencies.json',
);
logger.info('Adding develop dependencies for the project...');
if (!fs.existsSync(devDependenciesJsonPath)) {
logger.info('No additional develop dependencies.');
return;
}
let dependencies: any;
try {
dependencies = require(devDependenciesJsonPath);
} catch (err) {
throw new Error(
`Could not parse the template's devDependencies.json: ${err.message}`,
);
}
const dependenciesToInstall = Object.keys(dependencies).map(
depName => `${depName}@${dependencies[depName]}`,
try {
// "app" is usually the default value for Android apps with only 1 app
const {appFolder} = args;
const variant = args.variant.toLowerCase();
const buildDirectory = `${appFolder}/build/outputs/apk/${variant}`;
const apkFile = getInstallApkName(
appFolder,
adbPath,
variant,
device,
buildDirectory,
);
const pathToApk = `${buildDirectory}/${apkFile}`;
const adbArgs = ['-s', device, 'install', '-r', '-d', pathToApk];
logger.info(`Installing the app on the device "${device}"...`);
logger.debug(
`Running command "cd android && adb -s ${device} install -r -d ${pathToApk}"`,
);
execa.sync(adbPath, adbArgs, {stdio: 'inherit'});
} catch (error) {
throw new CLIError('Failed to install the app on the device.', error);
}
}
function startCustomDebugger({
watchFolders,
customDebugger,
}: {
watchFolders: Array;
customDebugger: string;
}) {
const folders = watchFolders.map(escapePath).join(' ');
const command = `${customDebugger} ${folders}`;
logger.info('Starting custom debugger by executing:', command);
exec(command, function(error) {
if (error !== null) {
logger.error('Error while starting custom debugger:', error.stack || '');
}
});
}
packageNameWithSuffix: string,
packageName: string,
adbPath: string,
mainActivity: string,
) {
try {
const adbArgs = [
'shell',
'am',
'start',
'-n',
`${packageNameWithSuffix}/${packageName}.${mainActivity}`,
];
if (device) {
adbArgs.unshift('-s', device);
logger.info(`Starting the app on "${device}"...`);
} else {
logger.info('Starting the app...');
}
logger.debug(`Running command "${adbPath} ${adbArgs.join(' ')}"`);
spawnSync(adbPath, adbArgs, {stdio: 'inherit'});
} catch (error) {
throw new CLIError('Failed to start the app.', error);
}
}
currentVersion,
projectDir,
);
if (!newVersion) {
return;
}
const patch = await getPatch(currentVersion, newVersion, ctx);
if (patch === null) {
return;
}
if (patch === '') {
logger.info('Diff has no changes to apply, proceeding further');
await installDeps(newVersion);
await installCocoaPodsDeps(projectDir, thirdPartyIOSDeps);
logger.success(
`Upgraded React Native to v${newVersion} 🎉. Now you can review and commit the changes`,
);
return;
}
let patchSuccess;
try {
fs.writeFileSync(tmpPatchFile, patch);
patchSuccess = await applyPatch(currentVersion, newVersion, tmpPatchFile);
} catch (error) {
throw new Error(error.stderr || error);
} finally {
if (contentChanged === 'changed') {
logger.info(
`${chalk.bold(relativeDestPath)} ` +
`has changed in the new version.\nDo you want to keep your ${relativeDestPath} or replace it with the ` +
'latest version?\nIf you ever made any changes ' +
"to this file, you'll probably want to keep it.\n" +
`You can see the new version here: ${absoluteSrcFilePath}\n` +
`Do you want to replace ${relativeDestPath}? ` +
'Answer y to replace, n to keep your version: ',
);
const answer = prompt();
if (answer === 'y') {
logger.info(`Replacing ${relativeDestPath}`);
return 'overwrite';
}
logger.info(`Keeping your ${relativeDestPath}`);
return 'keep';
}
if (contentChanged === 'identical') {
return 'keep';
}
throw new Error(
`Unknown file changed state: ${relativeDestPath}, ${contentChanged}`,
);
}
function printInstructions(title: string) {
logger.info(
[
'',
chalk.bgBlue.white.bold(` ${title} `),
' When you see Red Box with stack trace, you can click any ',
' stack frame to jump to the source file. The packager will launch your ',
' editor of choice. It will first look at REACT_EDITOR environment ',
' variable, then at EDITOR. To set it up, you can add something like ',
' export REACT_EDITOR=atom to your ~/.bashrc or ~/.zshrc depending on ',
' which shell you use.',
'',
].join('\n'),
);
}