create-expo-cljs-app
Version:
Create a react native application with Expo and Shadow-CLJS!
366 lines (295 loc) • 11.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _execa() {
const data = _interopRequireDefault(require("execa"));
_execa = function () {
return data;
};
return data;
}
function _chalk() {
const data = _interopRequireDefault(require("chalk"));
_chalk = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
var _adb = _interopRequireDefault(require("./adb"));
var _runOnAllDevices = _interopRequireDefault(require("./runOnAllDevices"));
var _tryRunAdbReverse = _interopRequireDefault(require("./tryRunAdbReverse"));
var _tryLaunchAppOnDevice = _interopRequireDefault(require("./tryLaunchAppOnDevice"));
var _getAdbPath = _interopRequireDefault(require("./getAdbPath"));
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
var _warnAboutManuallyLinkedLibs = _interopRequireDefault(require("../../link/warnAboutManuallyLinkedLibs"));
var _getAndroidProject = require("../../utils/getAndroidProject");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
function displayWarnings(config, args) {
(0, _warnAboutManuallyLinkedLibs.default)(config);
if (args.appFolder) {
_cliTools().logger.warn('Using deprecated "--appFolder" flag. Use "project.android.appName" in react-native.config.js instead.');
}
if (args.root) {
_cliTools().logger.warn('Using deprecated "--root" flag. App root is discovered automatically. Alternatively, set "project.android.sourceDir" in react-native.config.js.');
}
}
/**
* Starts the app on a connected Android emulator or device.
*/
async function runAndroid(_argv, config, args) {
displayWarnings(config, args);
const androidProject = (0, _getAndroidProject.getAndroidProject)(config);
if (args.jetifier) {
_cliTools().logger.info(`Running ${_chalk().default.bold('jetifier')} to migrate libraries to AndroidX. ${_chalk().default.dim('You can disable it using "--no-jetifier" flag.')}`);
try {
await (0, _execa().default)(require.resolve('jetifier/bin/jetify'), {
stdio: 'inherit'
});
} catch (error) {
throw new (_cliTools().CLIError)('Failed to run jetifier.', error);
}
}
if (!args.packager) {
return buildAndRun(args, androidProject);
}
return (0, _cliTools().isPackagerRunning)(args.port).then(result => {
if (result === 'running') {
_cliTools().logger.info('JS server already running.');
} else if (result === 'unrecognized') {
_cliTools().logger.warn('JS server not recognized, continuing with build...');
} else {
// result == 'not_running'
_cliTools().logger.info('Starting JS server...');
try {
startServerInNewWindow(args.port, args.terminal, config.reactNativePath);
} catch (error) {
_cliTools().logger.warn(`Failed to automatically start the packager server. Please run "react-native start" manually. Error details: ${error.message}`);
}
}
return buildAndRun(args, androidProject);
});
} // Builds the app and runs it on a connected emulator / device.
function buildAndRun(args, androidProject) {
process.chdir(androidProject.sourceDir);
const cmd = process.platform.startsWith('win') ? 'gradlew.bat' : './gradlew';
const {
appFolder
} = args;
const packageName = (0, _getAndroidProject.getPackageName)(androidProject, appFolder);
const adbPath = (0, _getAdbPath.default)();
if (args.deviceId) {
return runOnSpecificDevice(args, cmd, packageName, adbPath, androidProject);
} else {
return (0, _runOnAllDevices.default)(args, cmd, packageName, adbPath, androidProject);
}
}
function runOnSpecificDevice(args, gradlew, packageName, adbPath, androidProject) {
const devices = _adb.default.getDevices(adbPath);
const {
deviceId
} = args;
if (devices.length > 0 && deviceId) {
if (devices.indexOf(deviceId) !== -1) {
buildApk(gradlew, androidProject.sourceDir);
installAndLaunchOnDevice(args, deviceId, packageName, adbPath, androidProject);
} else {
_cliTools().logger.error(`Could not find device with the id: "${deviceId}". Please choose one of the following:`, ...devices);
}
} else {
_cliTools().logger.error('No Android device or emulator connected.');
}
}
function buildApk(gradlew, sourceDir) {
try {
// using '-x lint' in order to ignore linting errors while building the apk
const gradleArgs = ['build', '-x', 'lint'];
_cliTools().logger.info('Building the app...');
_cliTools().logger.debug(`Running command "${gradlew} ${gradleArgs.join(' ')}"`);
_execa().default.sync(gradlew, gradleArgs, {
stdio: 'inherit',
cwd: sourceDir
});
} catch (error) {
throw new (_cliTools().CLIError)('Failed to build the app.', error);
}
}
function tryInstallAppOnDevice(args, adbPath, device, androidProject) {
try {
// "app" is usually the default value for Android apps with only 1 app
const {
appName,
sourceDir
} = androidProject;
const {
appFolder
} = args;
const variant = args.variant.toLowerCase();
const buildDirectory = `${sourceDir}/${appName}/build/outputs/apk/${variant}`;
const apkFile = getInstallApkName(appFolder || appName, // TODO: remove appFolder
adbPath, variant, device, buildDirectory);
const pathToApk = `${buildDirectory}/${apkFile}`;
const adbArgs = ['-s', device, 'install', '-r', '-d', pathToApk];
_cliTools().logger.info(`Installing the app on the device "${device}"...`);
_cliTools().logger.debug(`Running command "cd android && adb -s ${device} install -r -d ${pathToApk}"`);
_execa().default.sync(adbPath, adbArgs, {
stdio: 'inherit'
});
} catch (error) {
throw new (_cliTools().CLIError)('Failed to install the app on the device.', error);
}
}
function getInstallApkName(appName, adbPath, variant, device, buildDirectory) {
const availableCPUs = _adb.default.getAvailableCPUs(adbPath, device); // check if there is an apk file like app-armeabi-v7a-debug.apk
for (const availableCPU of availableCPUs.concat('universal')) {
const apkName = `${appName}-${availableCPU}-${variant}.apk`;
if (_fs().default.existsSync(`${buildDirectory}/${apkName}`)) {
return apkName;
}
} // check if there is a default file like app-debug.apk
const apkName = `${appName}-${variant}.apk`;
if (_fs().default.existsSync(`${buildDirectory}/${apkName}`)) {
return apkName;
}
throw new (_cliTools().CLIError)('Could not find the correct install APK file.');
}
function installAndLaunchOnDevice(args, selectedDevice, packageName, adbPath, androidProject) {
(0, _tryRunAdbReverse.default)(args.port, selectedDevice);
tryInstallAppOnDevice(args, adbPath, selectedDevice, androidProject);
(0, _tryLaunchAppOnDevice.default)(selectedDevice, packageName, adbPath, args);
}
function startServerInNewWindow(port, terminal, reactNativePath) {
/**
* Set up OS-specific filenames and commands
*/
const isWindows = /^win/.test(process.platform);
const scriptFile = isWindows ? 'launchPackager.bat' : 'launchPackager.command';
const packagerEnvFilename = isWindows ? '.packager.bat' : '.packager.env';
const portExportContent = isWindows ? `set RCT_METRO_PORT=${port}` : `export RCT_METRO_PORT=${port}`;
/**
* Set up the `.packager.(env|bat)` file to ensure the packager starts on the right port.
*/
const launchPackagerScript = _path().default.join(reactNativePath, `scripts/${scriptFile}`);
/**
* Set up the `launchpackager.(command|bat)` file.
* It lives next to `.packager.(bat|env)`
*/
const scriptsDir = _path().default.dirname(launchPackagerScript);
const packagerEnvFile = _path().default.join(scriptsDir, packagerEnvFilename);
const procConfig = {
cwd: scriptsDir
};
/**
* Ensure we overwrite file by passing the `w` flag
*/
_fs().default.writeFileSync(packagerEnvFile, portExportContent, {
encoding: 'utf8',
flag: 'w'
});
if (process.platform === 'darwin') {
try {
return _execa().default.sync('open', ['-a', terminal, launchPackagerScript], procConfig);
} catch (error) {
return _execa().default.sync('open', [launchPackagerScript], procConfig);
}
}
if (process.platform === 'linux') {
try {
return _execa().default.sync(terminal, ['-e', `sh ${launchPackagerScript}`], { ...procConfig,
detached: true
});
} catch (error) {
// By default, the child shell process will be attached to the parent
return _execa().default.sync('sh', [launchPackagerScript], procConfig);
}
}
if (/^win/.test(process.platform)) {
// Awaiting this causes the CLI to hang indefinitely, so this must execute without await.
return (0, _execa().default)('cmd.exe', ['/C', launchPackagerScript], { ...procConfig,
detached: true,
stdio: 'ignore'
});
}
_cliTools().logger.error(`Cannot start the packager. Unknown platform ${process.platform}`);
return;
}
var _default = {
name: 'run-android',
description: 'builds your app and starts it on a connected Android emulator or device',
func: runAndroid,
options: [{
name: '--root <string>',
description: '[DEPRECATED - root is discovered automatically] Override the root directory for the android build (which contains the android directory)',
default: ''
}, {
name: '--variant <string>',
description: "Specify your app's build variant",
default: 'debug'
}, {
name: '--appFolder <string>',
description: '[DEPRECATED – use "project.android.appName" in react-native.config.js] Specify a different application folder name for the android source. If not, we assume is "app"'
}, {
name: '--appId <string>',
description: 'Specify an applicationId to launch after build. If not specified, `package` from AndroidManifest.xml will be used.',
default: ''
}, {
name: '--appIdSuffix <string>',
description: 'Specify an applicationIdSuffix to launch after build.',
default: ''
}, {
name: '--main-activity <string>',
description: 'Name of the activity to start',
default: 'MainActivity'
}, {
name: '--deviceId <string>',
description: 'builds your app and starts it on a specific device/simulator with the ' + 'given device id (listed by running "adb devices" on the command line).'
}, {
name: '--no-packager',
description: 'Do not launch packager while building'
}, {
name: '--port <number>',
default: process.env.RCT_METRO_PORT || 8081,
parse: Number
}, {
name: '--terminal <string>',
description: 'Launches the Metro Bundler in a new window using the specified terminal path.',
default: (0, _cliTools().getDefaultUserTerminal)()
}, {
name: '--tasks <list>',
description: 'Run custom Gradle tasks. By default it\'s "installDebug"',
parse: val => val.split(',')
}, {
name: '--no-jetifier',
description: 'Do not run "jetifier" – the AndroidX transition tool. By default it runs before Gradle to ease working with libraries that don\'t support AndroidX yet. See more at: https://www.npmjs.com/package/jetifier.'
}]
};
exports.default = _default;
//# sourceMappingURL=index.js.map
;