1import chalk from 'chalk'; 2import semver from 'semver'; 3import inquirer from 'inquirer'; 4import { Command } from '@expo/commander'; 5 6import * as IosVersioning from '../versioning/ios'; 7import * as AndroidVersioning from '../versioning/android'; 8import { Platform, getSDKVersionsAsync, getOldestSDKVersionAsync } from '../ProjectVersions'; 9 10type ActionOptions = { 11 platform: Platform; 12 sdkVersion?: string; 13}; 14 15const SUPPORTED_PLATFORMS: Platform[] = ['ios', 'android']; 16 17async function getOldestOrAskForSDKVersionAsync(platform: Platform): Promise<string | undefined> { 18 const sdkVersions = await getSDKVersionsAsync(platform); 19 const defaultSdkVersion = await getOldestSDKVersionAsync(platform); 20 21 if (defaultSdkVersion && process.env.CI) { 22 console.log( 23 `${chalk.red('`--sdkVersion`')} not provided - defaulting to ${chalk.cyan(defaultSdkVersion)}` 24 ); 25 return defaultSdkVersion; 26 } 27 28 const { sdkVersion } = await inquirer.prompt<{ sdkVersion: string }>([ 29 { 30 type: 'list', 31 name: 'sdkVersion', 32 message: 'What is the SDK version that you want to remove?', 33 default: defaultSdkVersion, 34 choices: sdkVersions, 35 validate(value) { 36 if (!semver.valid(value)) { 37 return `Invalid version: ${chalk.cyan(value)}`; 38 } 39 return true; 40 }, 41 }, 42 ]); 43 return sdkVersion; 44} 45 46async function askForPlatformAsync(): Promise<Platform> { 47 if (process.env.CI) { 48 throw new Error(`Run with \`--platform <${SUPPORTED_PLATFORMS.join(' | ')}>\`.`); 49 } 50 51 const { platform } = await inquirer.prompt<{ platform: Platform }>([ 52 { 53 type: 'list', 54 name: 'platform', 55 message: 'Choose a platform from which you want to remove SDK version:', 56 default: SUPPORTED_PLATFORMS[0], 57 choices: SUPPORTED_PLATFORMS, 58 }, 59 ]); 60 61 return platform; 62} 63 64async function action(options: ActionOptions) { 65 const platform = options.platform || (await askForPlatformAsync()); 66 const sdkVersion = 67 options.sdkVersion || (await getOldestOrAskForSDKVersionAsync(options.platform)); 68 69 if (!sdkVersion) { 70 throw new Error('Oldest SDK version not found. Try to run with `--sdkVersion <SDK version>`.'); 71 } 72 73 switch (platform) { 74 case 'ios': 75 return IosVersioning.removeVersionAsync(sdkVersion); 76 case 'android': 77 return AndroidVersioning.removeVersionAsync(sdkVersion); 78 default: 79 throw new Error(`Platform '${platform}' is not supported.`); 80 } 81} 82 83export default (program: Command) => { 84 program 85 .command('remove-sdk-version') 86 .alias('remove-sdk', 'rm-sdk', 'rs') 87 .description('Removes SDK version.') 88 .usage( 89 ` 90 91To remove versioned code for the oldest supported SDK on iOS, run: 92${chalk.gray('>')} ${chalk.italic.cyan('et remove-sdk-version --platform ios')}` 93 ) 94 .option( 95 '-p, --platform <string>', 96 `Specifies a platform for which the SDK code should be removed. Supported platforms: ${SUPPORTED_PLATFORMS.map( 97 (platform) => chalk.cyan(platform) 98 ).join(', ')}.` 99 ) 100 .option( 101 '-s, --sdkVersion [string]', 102 'SDK version to remove. Defaults to the oldest supported SDK version.' 103 ) 104 .asyncAction(action); 105}; 106