Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
await fse.writeFile(path.resolve('app.json'), JSON.stringify(appJson, null, 2));
log(chalk.green('Wrote to app.json, please update it manually in the future.'));
// This is validated later...
let defaultDependencies: any = {};
let defaultDevDependencies: any = {};
/**
* Extract the template and copy it over
*/
try {
const tempDir = temporary.directory();
await Exp.extractTemplateAppAsync(templateSpec, tempDir, appJson);
fse.copySync(path.join(tempDir, 'ios'), path.join(projectRoot, 'ios'));
fse.copySync(path.join(tempDir, 'android'), path.join(projectRoot, 'android'));
const { dependencies, devDependencies } = JsonFile.read(path.join(tempDir, 'package.json'));
defaultDependencies = ensureDependenciesMap(dependencies);
defaultDevDependencies = devDependencies;
log('Successfully copied template native code.');
} catch (e) {
log(chalk.red(e.message));
log(chalk.red(`Eject failed, see above output for any issues.`));
log(chalk.yellow('You may want to delete the `ios` and/or `android` directories.'));
process.exit(1);
}
log(`Updating your package.json...`);
if (!pkg.scripts) {
pkg.scripts = {};
}
delete pkg.scripts.eject;
pkg.scripts.start = 'react-native start';
async function getTemplateSubstitutions() {
try {
return await new JsonFile(path.join(EXPONENT_DIR, 'secrets', 'keys.json')).readAsync();
} catch (e) {
// Don't have access to decrypted secrets, use public keys
console.log('generate-dynamic-macros is falling back to `template-files/keys.json`');
return await new JsonFile(path.join(EXPONENT_DIR, 'template-files', 'keys.json')).readAsync();
}
}
async function _bumpVersionsAsync({
pkg,
newVersion,
shouldPublish,
}: PipelineConfig): Promise {
if (!shouldPublish) {
return;
}
console.log(`Updating versions in ${chalk.green(pkg.packageName)} package... ☝️`);
await JsonFile.setAsync(path.join(pkg.path, 'package.json'), 'version', newVersion);
console.log(chalk.yellow('>'), `Updated package version in ${chalk.magenta('package.json')}`);
if (fs.existsSync(path.join(pkg.path, 'android/build.gradle'))) {
// update version and versionName in android/build.gradle
const buildGradlePath = path.relative(EXPO_DIR, path.join(pkg.path, 'android/build.gradle'));
const sedPatterns = [
`s/version\\s*=\\s*'[^']*'/version = '${newVersion}'/g`,
`s/versionName\\s*"[^"]*"/versionName "${newVersion}"/g`,
];
for (const sedPattern of sedPatterns) {
await _spawnAsync(SED, ['-i', '--', sedPattern, buildGradlePath]);
}
},
},
]);
// Obtain the tag for the template.
const { tag } = await inquirer.prompt<{ tag: string }>([
{
type: 'input',
name: 'tag',
message: `How to tag ${chalk.green(template.name)}@${chalk.red(newVersion)}?`,
default: semver.prerelease(newVersion) ? 'next' : `sdk-${semver.major(options.sdkVersion)}`,
},
]);
// Update package version in `package.json`
await JsonFile.setAsync(path.join(template.path, 'package.json'), 'version', newVersion);
const appJsonPath = path.join(template.path, 'app.json');
if (
(await fs.exists(appJsonPath)) &&
(await JsonFile.getAsync(appJsonPath, 'expo.sdkVersion', null))
) {
// Make sure SDK version in `app.json` is correct
console.log(
`Setting ${chalk.magenta('expo.sdkVersion')} to ${chalk.green(
options.sdkVersion
)} in template's app.json...`
);
await JsonFile.setAsync(
path.join(template.path, 'app.json'),
'expo.sdkVersion',
// Update package version in `package.json`
await JsonFile.setAsync(path.join(template.path, 'package.json'), 'version', newVersion);
const appJsonPath = path.join(template.path, 'app.json');
if (
(await fs.exists(appJsonPath)) &&
(await JsonFile.getAsync(appJsonPath, 'expo.sdkVersion', null))
) {
// Make sure SDK version in `app.json` is correct
console.log(
`Setting ${chalk.magenta('expo.sdkVersion')} to ${chalk.green(
options.sdkVersion
)} in template's app.json...`
);
await JsonFile.setAsync(
path.join(template.path, 'app.json'),
'expo.sdkVersion',
options.sdkVersion
);
}
console.log(`Publishing ${chalk.green(template.name)}@${chalk.red(newVersion)}...`);
const moreArgs: string[] = [];
if (tag) {
// Assign custom tag in the publish command, so we don't accidentally publish as latest.
moreArgs.push('--tag', tag);
}
// Publish to NPM registry
buildGradlePath,
]);
console.log(
chalk.yellow('>'),
`Updated version code ${chalk.cyan(String(versionCodeInt))} -> ${chalk.cyan(
String(newVersionCode)
)}`,
`in ${chalk.magenta('android/build.gradle')}`
);
}
}
// Add unimodules to bundledNativeModules.json so the correct version will be installed by `expo install`.
if (pkg.isUnimodule()) {
await JsonFile.setAsync(
path.join(EXPO_DIR, 'packages/expo/bundledNativeModules.json'),
pkg.packageName,
`~${newVersion}`
);
console.log(
chalk.yellow('>'),
`Updated package version in`,
chalk.magenta('packages/expo/bundledNativeModules.json')
);
}
await _updateWorkspaceDependenciesAsync({ pkg, newVersion } as PipelineConfig);
console.log();
}
if (unsupportedPackages[dep]) {
delete packageJson.dependencies[dep];
unsupportedPackagesUsed.push(dep);
}
});
// TODO: we don't actually support index.android.js and index.ios.js right now!
if (
projectEntryPoint !== 'index.*.js' &&
projectEntryPoint !== 'index.js' &&
projectEntryPoint !== 'index.ios.js' &&
projectEntryPoint !== 'index.android.js'
) {
packageJson.main = projectEntryPoint;
}
await JsonFile.writeAsync(packageJsonTargetPath, packageJson);
console.log('Updated package.json');
// TODO: Add import Expo from 'expo'; at the top of main file
// Copy babelrc
await JsonFile.writeAsync(babelRcTargetPath, babelRcTemplate);
console.log('Updated .babelrc');
// Save next steps to a file, display, exit
await installAndInstructAsync(projectDir, unsupportedPackagesUsed);
});
// TODO: we don't actually support index.android.js and index.ios.js right now!
if (
projectEntryPoint !== 'index.*.js' &&
projectEntryPoint !== 'index.js' &&
projectEntryPoint !== 'index.ios.js' &&
projectEntryPoint !== 'index.android.js'
) {
packageJson.main = projectEntryPoint;
}
await JsonFile.writeAsync(packageJsonTargetPath, packageJson);
console.log('Updated package.json');
// TODO: Add import Expo from 'expo'; at the top of main file
// Copy babelrc
await JsonFile.writeAsync(babelRcTargetPath, babelRcTemplate);
console.log('Updated .babelrc');
// Save next steps to a file, display, exit
await installAndInstructAsync(projectDir, unsupportedPackagesUsed);
});
{ projectName, projectDescription, projectEntryPoint }: params
) {
let projectSlug = slug(projectName.toLowerCase());
let expJsonTargetPath = path.join(projectDir, '/exp.json');
let babelRcTargetPath = path.join(projectDir, '/.babelrc');
let packageJsonSourcePath = path.join(projectDir, '/package.json');
let packageJsonTargetPath = path.join(projectDir, '/package.json');
// Add values to exp.json, save to given path
let expJson = { ...expJsonTemplate };
expJson.name = projectName;
expJson.description = projectDescription || 'No description';
expJson.slug = projectSlug;
await JsonFile.writeAsync(expJsonTargetPath, expJson);
console.log('Wrote exp.json');
// Add entry point and dependencies to package.json
let unsupportedPackagesUsed = [];
let packageJson = await JsonFile.readAsync(packageJsonSourcePath);
packageJson.dependencies = { ...packageJson.dependencies, ...dependencies };
// Remove
Object.keys(packageJson.dependencies).forEach(dep => {
if (unsupportedPackages[dep]) {
delete packageJson.dependencies[dep];
unsupportedPackagesUsed.push(dep);
}
});
const { tag } = await inquirer.prompt<{ tag: string }>([
{
type: 'input',
name: 'tag',
message: `How to tag ${chalk.green(template.name)}@${chalk.red(newVersion)}?`,
default: semver.prerelease(newVersion) ? 'next' : `sdk-${semver.major(options.sdkVersion)}`,
},
]);
// Update package version in `package.json`
await JsonFile.setAsync(path.join(template.path, 'package.json'), 'version', newVersion);
const appJsonPath = path.join(template.path, 'app.json');
if (
(await fs.exists(appJsonPath)) &&
(await JsonFile.getAsync(appJsonPath, 'expo.sdkVersion', null))
) {
// Make sure SDK version in `app.json` is correct
console.log(
`Setting ${chalk.magenta('expo.sdkVersion')} to ${chalk.green(
options.sdkVersion
)} in template's app.json...`
);
await JsonFile.setAsync(
path.join(template.path, 'app.json'),
'expo.sdkVersion',
options.sdkVersion
);
}
console.log(`Publishing ${chalk.green(template.name)}@${chalk.red(newVersion)}...`);