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