Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
descriptor
)
baseComposite = baseComposite || compositeGenConfig?.baseComposite
resolutions = compositeGenConfig?.resolutions
}
// Because this command can only be stoped through `CTRL+C` (or killing the process)
// we listen for the SIGINT signal and then just exit the process
// This is needed for tmp module to do its cleanup, otherwise the temporary directory
// is not removed after `CTRL+C` is done
process.on('SIGINT', () => process.exit())
compositeDir = compositeDir || createTmpDir()
log.trace(`Temporary composite directory is ${compositeDir}`)
const composite = await kax
.task(`Generating composite in ${compositeDir}`)
.run(
Composite.generate({
baseComposite,
extraJsDependencies: extraJsDependencies || undefined,
jsApiImplDependencies: jsApiImpls,
miniApps: miniapps!,
outDir: compositeDir,
resolutions,
})
)
// Third party native modules
const nativeDependencies = await composite.getNativeDependencies()
const nativeModules: PackagePath[] = [
...nativeDependencies.thirdPartyInManifest,
path.join(outDir, 'package.json'),
JSON.stringify(compositePackageJson, null, 2),
'utf8'
)
// Now that the composite package.json is similar to the one used to generated yarn.lock
// we can run yarn install to get back to the exact same dependency graph as the previously
// generated composite
await yarn.install()
await runYarnUsingMiniAppDeltas(miniAppsDeltas)
} else {
// No yarn.lock path was provided, just add miniapps one by one
log.debug('[generateMiniAppsComposite] no yarn lock provided')
await yarn.init()
for (const miniappPath of miniappsPaths) {
await yarn.add(miniappPath)
}
const packageJsonPath = path.join(outDir, 'package.json')
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
packageJson.scripts = {
start: 'node node_modules/react-native/local-cli/cli.js start',
}
fs.writeFileSync(
packageJsonPath,
JSON.stringify(packageJson, null, 2),
'utf8'
)
}
for (const extraJsDependency of extraJsDependencies) {
await yarn.add(extraJsDependency)
function showVersion() {
// get electrode-native local-cli version
if (config.get('platformVersion')) {
log.info(`ern-local-cli : ${config.get('platformVersion')}`)
}
// get electrode-native global-cli version
const packageInfo = JSON.parse(
execSync('npm ls -g electrode-native --json').toString()
)
if (packageInfo && packageInfo.dependencies) {
log.info(
`electrode-native : ${
packageInfo.dependencies['electrode-native'].version
}`
)
}
}
// code push is not making a real use of this data
// Investigate further.
// https://github.com/Microsoft/code-push/blob/master/cli/script/command-executor.ts#L1246
compositePackageJson.dependencies['react-native'] =
reactNativePackageJson.version
compositePackageJson.name = 'container'
compositePackageJson.version = '0.0.1'
fs.writeFileSync(
'package.json',
JSON.stringify(compositePackageJson, null, 2)
)
}
log.debug('Creating index.android.js')
await writeFile('index.android.js', entryIndexJsContent)
log.debug('Creating index.ios.js')
await writeFile('index.ios.js', entryIndexJsContent)
}
public async postBundle(
config: ContainerGeneratorConfig,
bundle: BundlingResult
) {
if (this.getJavaScriptEngine(config) === JavaScriptEngine.HERMES) {
const hermesVersion =
config.androidConfig.hermesVersion || android.DEFAULT_HERMES_VERSION
const hermesCli = await kax
.task(`Installing hermes-engine@${hermesVersion}`)
.run(HermesCli.fromVersion(hermesVersion))
const hermesBundle = await kax
.task('Compiling JS bundle to Hermes bytecode')
.run(
hermesCli.compileReleaseBundle({ jsBundlePath: bundle.bundlePath })
)
if (bundle.sourceMapPath) {
// Unfortunately Hermes binary does not give control over the
// location of generated source map. It just generates it in
// the same directory as the hermes bundle, with the same name
// as the bundle, with a new .map extension.
// We don't want to keep the generated source map in the container,
// So if the JS bundle had an associated source map generated,
// just overwrite it with the Hermes one ...
shell.mv(hermesBundle.hermesSourceMapPath, bundle.sourceMapPath)
} else {
// ... otherwise just remove it from the container
extra = parseJsonFromStringOrFile(extraFile.toString())
}
// ==================================================================
// Legacy code. To be deprecated
let publisherName = publisherFromCauldron.name
if (publisherName === 'github') {
log.warn(
`Your Cauldron is using the 'github' publisher which has been deprecated.
Please rename 'github' publisher name to 'git' in your Cauldron to get rid of this warning.`
)
publisherName = 'git'
}
// ==================================================================
await kax.task(`Running Container Publisher ${publisherName}`).run(
publishContainer({
containerPath,
containerVersion,
extra,
platform: napDescriptor.platform,
publisher: publisherName,
url: publisherFromCauldron.url,
})
)
}
log.info(
`Published new Container version ${containerVersion} for ${napDescriptor.toString()}`
)
}
}
// Otherwise any module dependent on r-n won't be able to use it
config.plugins = [
...(reactNativePlugin ? [reactNativePlugin] : []),
...config.plugins.filter(plugin => plugin !== reactNativePlugin),
]
shell.pushd(config.outDir)
try {
if (fillContainerHull) {
await fillContainerHull(config)
}
} finally {
shell.popd()
}
const bundlingResult: BundlingResult = await kax
.task('Bundling MiniApps')
.run(
bundleMiniAppsFromComposite({
compositeDir: config.composite.path,
outDir: config.outDir,
platform: config.targetPlatform,
sourceMapOutput: config.sourceMapOutput,
})
)
if (postBundle) {
await postBundle(config, bundlingResult)
}
if (!config.ignoreRnpmAssets) {
copyRnpmAssets(
await runCaudronBundleGen(napDescriptor, {
compositeMiniAppDir,
outDir,
})
// Update container metadata
const metadata = await fileUtils.readJSON(
getContainerMetadataPath(outDir)
)
const miniapps = await cauldron.getContainerMiniApps(napDescriptor)
const jsApiImpls = await cauldron.getContainerJsApiImpls(napDescriptor)
metadata.miniApps = miniapps.map(m => m.fullPath)
metadata.jsApiImpls = jsApiImpls.map(j => j.fullPath)
metadata.ernVersion = Platform.currentVersion
await fileUtils.writeJSON(getContainerMetadataPath(outDir), metadata)
} catch (e) {
log.error(`Something went wrong trying to regenerate JS bundle only`)
log.error(e)
log.error(`Falling back to full Container generation`)
jsBundleOnly = false
}
} else if (publishOnly) {
log.info(`No changes from ${currentContainerVersion}`)
log.info('Only publishing')
// Update container metadata
const metadata = await fileUtils.readJSON(
getContainerMetadataPath(outDir)
)
metadata.ernVersion = Platform.currentVersion
await fileUtils.writeJSON(getContainerMetadataPath(outDir), metadata)
}
// Full container generation
)
for (const file of files) {
if (
(file.startsWith(pathLibSrcMainJavaCom) &&
!file.startsWith(pathLibSrcMainJavaComWalmartlabsErnContainer)) ||
file.startsWith(pathLibSrcMainAssets)
) {
// We don't want to Mustache process library files. It can lead to bad things
// We also don't want to process assets files ...
// We just want to process container specific code (which contains mustache templates)
log.debug(`Skipping mustaching of ${file}`)
continue
}
log.debug(`Mustaching ${file}`)
const pathToFile = path.join(config.outDir, file)
await mustacheUtils.mustacheRenderToOutputFileUsingTemplateFile(
pathToFile,
mustacheView,
pathToFile
)
}
log.debug('Creating miniapp activities')
for (const miniApp of config.miniApps) {
const activityFileName = `${miniApp.pascalCaseName}Activity.java`
log.debug(`Creating ${activityFileName}`)
const pathToMiniAppActivityMustacheTemplate = path.join(
PATH_TO_TEMPLATES_DIR,
'MiniAppActivity.mustache'
)
const pathToOutputActivityFile = path.join(
'You cannot CodePush to a non existing native application version.',
},
sameNativeApplicationAndPlatform: {
descriptors,
extraErrorMessage:
'You can only pass descriptors that match the same native application and version',
},
})
} else if (descriptors.length === 0 && !semVerDescriptor) {
// User provided no descriptors, nor a semver descriptor
descriptors = await askUserToChooseOneOrMoreNapDescriptorFromCauldron({
onlyReleasedVersions: true,
})
} else if (semVerDescriptor) {
// User provided a semver Descriptor
const semVerNapDescriptor = AppVersionDescriptor.fromString(
semVerDescriptor
)
const cauldron = await getActiveCauldron()
descriptors = await cauldron.getDescriptorsMatchingSemVerDescriptor(
semVerNapDescriptor
)
if (descriptors.length === 0) {
throw new Error(`No versions matching ${semVerDescriptor} were found`)
} else {
log.info(
'CodePush release will target the following native application descriptors :'
)
for (const descriptor of descriptors) {
log.info(`- ${descriptor}`)
}
if (!skipConfirmation) {