Compare commits

...
11 Commits
Author SHA1 Message Date
Szymon Dziedzic a67838dc81 update CHANGELOG.md 2023-01-20 10:05:15 +00:00
Szymon Dziedzic 859f8e3adb test 2023-01-20 11:03:29 +01:00
Szymon Dziedzic 3e3ec87622 [ENG-7223][ci] run tests on each changelog workflow automated commit (#1640)
* [ci] add test changelog workflow

* update main changelog workflow

* delete changelog_2 workflow

* use correct command

* select last commit author as automated changelog change author
2023-01-20 11:01:12 +01:00
Wojciech Kozyra f1cf92d63a [eas-cli] Print error message sent from server (#1639) 2023-01-19 14:17:59 +01:00
Brent Vatne 7096daa116 [eas-cli] Switch to using M1 by default when running build:configure (#1637) 2023-01-18 11:35:24 -08:00
Dominik Sokal 6429e70a9a print disabled resource class labels (#1635)
* print disabled resource class labels

* update CHANGELOG.md
2023-01-18 18:26:21 +01:00
Wojciech Kozyra 083381da82 [eas-cli] Automatically promote new cli release to staging on EAS Build (#1624) 2023-01-16 10:08:46 +01:00
Dominik Sokal 1c1af2da86 remove nx and upgrade lerna (https://github.com/lerna/lerna/pull/3495) 2023-01-13 10:40:06 +01:00
Wojciech Kozyra 72ce75e1ee [eas-cli] Base implementation for running builds directly from GitHub (#1568) 2023-01-13 10:01:53 +01:00
Wojciech Kozyra ea553a1025 [eas-cli] Remove workaround for gitignore with trailing backslash (#1622)
* [eas-cli] Remove workaround (fixed upstream)

* update CHANGELOG.md
2023-01-12 15:27:23 +01:00
Expo CI 3a6bcb3f2e update CHANGELOG.md 2023-01-12 11:06:59 +00:00
15 changed files with 692 additions and 533 deletions

No files matched your search

+3
View File
@@ -10,6 +10,8 @@ jobs:
if: ${{ github.event.issue.pull_request && github.event.issue.user.login == github.event.comment.user.login && startsWith(github.event.comment.body, '/changelog-entry ') }}
steps:
- uses: actions/checkout@v2
with:
token: ${{ secrets.EXPO_BOT_PAT }}
- uses: actions/setup-node@v2
with:
node-version: 18
@@ -44,3 +46,4 @@ jobs:
git add CHANGELOG.md
git commit -m "update CHANGELOG.md"
git push
+13 -5
View File
@@ -36,10 +36,10 @@ jobs:
yarn pretarball-ci
yarn oclif pack:tarballs --no-xz --targets linux-x64,linux-arm
- id: x64
run: echo "::set-output name=filename::$(ls eas-*-x64.tar.gz)"
run: echo "filename=$(ls eas-*-x64.tar.gz)" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}/packages/eas-cli/dist
- id: arm
run: echo "::set-output name=filename::$(ls eas-*-arm.tar.gz)"
run: echo "filename=$(ls eas-*-arm.tar.gz)" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}/packages/eas-cli/dist
- name: Upload linux-x64 tarball
uses: actions/upload-release-asset@v1
@@ -77,7 +77,7 @@ jobs:
yarn pretarball-ci
yarn oclif pack:tarballs --no-xz --targets darwin-x64
- id: x64
run: echo "::set-output name=filename::$(ls eas-*-x64.tar.gz)"
run: echo "filename=$(ls eas-*-x64.tar.gz)" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}/packages/eas-cli/dist
- name: Upload darwin-x64 tarball
uses: actions/upload-release-asset@v1
@@ -105,10 +105,10 @@ jobs:
yarn oclif pack:win
working-directory: ${{ github.workspace }}/packages/eas-cli
- id: x64
run: echo "::set-output name=filename::$(ls eas-*-x64.exe)"
run: echo "filename=$(ls eas-*-x64.exe)" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}/packages/eas-cli/dist/win32
- id: x86
run: echo "::set-output name=filename::$(ls eas-*-x86.exe)"
run: echo "filename=$(ls eas-*-x86.exe)" >> $GITHUB_OUTPUT
working-directory: ${{ github.workspace }}/packages/eas-cli/dist/win32
- name: Upload x64 installer
uses: actions/upload-release-asset@v1
@@ -147,6 +147,14 @@ jobs:
run: yarn lerna publish from-package --yes --no-verify-access
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
- name: Add latest-eas-build-staging tag
run: |
VERSION=$(cat lerna.json | jq -r .version)
echo //registry.npmjs.org/:_authToken=$NODE_AUTH_TOKEN > ~/.npmrc
npm dist-tag add eas-cli@$VERSION latest-eas-build-staging
echo "Run \"npm dist-tag add eas-cli@$VERSION latest-eas-build\" to promote it to production."
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
release-changelog:
name: Update changelog and publish release
runs-on: ubuntu-latest
+15
View File
@@ -8,6 +8,21 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Add `--json` flag to `eas config` command. ([#1568](https://github.com/expo/eas-cli/pull/1568) by [@wkozyra95](https://github.com/wkozyra95))
- Add M1 resource class configuration to default eas.json when running eas build:configure on a new project. ([#1637](https://github.com/expo/eas-cli/pull/1637) by [@brentvatne](https://github.com/brentvatne))
### 🐛 Bug fixes
### 🧹 Chores
- Remove unnecessary workaround for trailing backslash in .gitignore. ([#1622](https://github.com/expo/eas-cli/pull/1622) by [@wkozyra95](https://github.com/wkozyra95))
- Internal command that will be run on EAS worker when building from GitHub. ([#1568](https://github.com/expo/eas-cli/pull/1568) by [@wkozyra95](https://github.com/wkozyra95))
- Make the disabled tier error message more descriptive. ([#1635](https://github.com/expo/eas-cli/pull/1635) by [@dsokal](https://github.com/dsokal))
- Control some of the EAS Build error messages server-side. ([#1639](https://github.com/expo/eas-cli/pull/1639) by [@wkozyra95](https://github.com/wkozyra95))
- Test. ([#1646](https://github.com/expo/eas-cli/pull/1646) by [@szdziedzic](https://github.com/szdziedzic))
## [3.3.2](https://github.com/expo/eas-cli/releases/tag/v3.3.2) - 2023-01-12
### 🐛 Bug fixes
- Add missing key information about updates in `eas update --json` and `eas update:view --json`. ([#1619](https://github.com/expo/eas-cli/pull/1619) by [@byCedric](https://github.com/byCedric))
+4
View File
@@ -12,3 +12,7 @@ The algorithm works as follows:
- If there are any entries in the "🛠 Breaking changes" section, bump the MAJOR version.
- Otherwise, if there are any entries in the "🎉 New features", bump the MINOR version.
- Otherwise, bump the PATCH version.
## Updating EAS CLI version on EAS Build
The release process promotes the new version to staging. After verifying it works there, you can promote it to production with `npm dist-tag add eas-cli@{version} latest-eas-build`.
+1 -2
View File
@@ -27,8 +27,7 @@
"eslint-plugin-node": "11.1.0",
"jest": "29.3.1",
"jest-watch-typeahead": "2.2.1",
"lerna": "6.3.0",
"nx": "15.4.5",
"lerna": "6.4.1",
"oclif": "3.4.3",
"prettier": "2.8.2",
"ts-jest": "29.0.3",
+39 -39
View File
@@ -1,5 +1,6 @@
import { ArchiveSource, ArchiveSourceType, Job, Metadata, Platform } from '@expo/eas-build-job';
import { CredentialsSource } from '@expo/eas-json';
import assert from 'assert';
import chalk from 'chalk';
import cliProgress from 'cli-progress';
import fs from 'fs-extra';
@@ -28,11 +29,12 @@ import {
} from '../platform';
import { uploadFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { printJsonOnlyOutput } from '../utils/json';
import { createProgressTracker } from '../utils/progress';
import { sleepAsync } from '../utils/promise';
import { getVcsClient } from '../vcs';
import { BuildContext } from './context';
import { runLocalBuildAsync } from './local';
import { LocalBuildMode, runLocalBuildAsync } from './local';
import { collectMetadataAsync } from './metadata';
import { printDeprecationWarnings } from './utils/printBuildInfo';
import { makeProjectTarballAsync, reviewAndCommitChangesAsync } from './utils/repository';
@@ -107,15 +109,24 @@ export async function prepareBuildRequestForPlatformAsync<
);
}
const projectArchive = ctx.localBuildOptions.enable
? ({
type: ArchiveSourceType.PATH,
path: (await makeProjectTarballAsync()).path,
} as const)
: ({
type: ArchiveSourceType.GCS,
bucketKey: await uploadProjectAsync(ctx),
} as const);
let projectArchive: ArchiveSource | undefined;
if (ctx.localBuildOptions.localBuildMode === LocalBuildMode.LOCAL_BUILD_PLUGIN) {
projectArchive = {
type: ArchiveSourceType.PATH,
path: (await makeProjectTarballAsync()).path,
};
} else if (ctx.localBuildOptions.localBuildMode === LocalBuildMode.INTERNAL) {
projectArchive = {
type: ArchiveSourceType.PATH,
path: process.cwd(),
};
} else if (!ctx.localBuildOptions.localBuildMode) {
projectArchive = {
type: ArchiveSourceType.GCS,
bucketKey: await uploadProjectAsync(ctx),
};
}
assert(projectArchive);
const metadata = await collectMetadataAsync(ctx);
const buildParams = resolveBuildParamsInput(ctx);
@@ -125,22 +136,36 @@ export async function prepareBuildRequestForPlatformAsync<
});
return async () => {
if (ctx.localBuildOptions.enable) {
if (ctx.localBuildOptions.localBuildMode === LocalBuildMode.LOCAL_BUILD_PLUGIN) {
await runLocalBuildAsync(job, metadata, ctx.localBuildOptions);
return undefined;
} else {
} else if (ctx.localBuildOptions.localBuildMode === LocalBuildMode.INTERNAL) {
printJsonOnlyOutput({ job, metadata });
return undefined;
} else if (!ctx.localBuildOptions.localBuildMode) {
try {
return await sendBuildRequestAsync(builder, job, metadata, buildParams);
} catch (error: any) {
handleBuildRequestError(error, job.platform);
}
} else {
throw new Error('Unknown localBuildMode.');
}
};
}
const SERVER_SIDE_DEFINED_ERRORS = [
'TURTLE_DEPRECATED_JOB_FORMAT',
'EAS_BUILD_FREE_TIER_DISABLED',
'EAS_BUILD_FREE_TIER_DISABLED_IOS',
'EAS_BUILD_FREE_TIER_DISABLED_ANDROID',
];
function handleBuildRequestError(error: any, platform: Platform): never {
if (error?.graphQLErrors?.[0]?.extensions?.errorCode === 'TURTLE_DEPRECATED_JOB_FORMAT') {
Log.error('EAS Build API has changed. Upgrade to the latest eas-cli version.');
Log.debug(JSON.stringify(error.graphQLErrors, null, 2));
if (SERVER_SIDE_DEFINED_ERRORS.includes(error?.graphQLErrors?.[0]?.extensions?.errorCode)) {
Log.error(error?.graphQLErrors?.[0]?.message);
throw new Error('Build request failed.');
} else if (
error?.graphQLErrors?.[0]?.extensions?.errorCode === 'EAS_BUILD_DOWN_FOR_MAINTENANCE'
@@ -151,31 +176,6 @@ function handleBuildRequestError(error: any, platform: Platform): never {
)} for updates.`
);
throw new Error('Build request failed.');
} else if (error?.graphQLErrors?.[0]?.extensions?.errorCode === 'EAS_BUILD_FREE_TIER_DISABLED') {
Log.error(
`EAS Build free tier is temporarily disabled and we are not accepting any new builds. Try again later. ${learnMore(
'https://expo.fyi/eas-build-queues'
)}`
);
throw new Error('Build request failed.');
} else if (
error?.graphQLErrors?.[0]?.extensions?.errorCode === 'EAS_BUILD_FREE_TIER_DISABLED_IOS'
) {
Log.error(
`EAS Build free tier is temporarily disabled for iOS and we are not accepting any new builds. Try again later. ${learnMore(
'https://expo.fyi/eas-build-queues'
)}`
);
throw new Error('Build request failed.');
} else if (
error?.graphQLErrors?.[0]?.extensions?.errorCode === 'EAS_BUILD_FREE_TIER_DISABLED_ANDROID'
) {
Log.error(
`EAS Build free tier is temporarily disabled for Android and we are not accepting any new builds. Try again later. ${learnMore(
'https://expo.fyi/eas-build-queues'
)}`
);
throw new Error('Build request failed.');
} else if (
error?.graphQLErrors?.[0]?.extensions?.errorCode === 'EAS_BUILD_TOO_MANY_PENDING_BUILDS'
) {
+21 -3
View File
@@ -1,5 +1,5 @@
import { Platform, Workflow } from '@expo/eas-build-job';
import { EasJson, EasJsonAccessor } from '@expo/eas-json';
import { EasJson, EasJsonAccessor, ResourceClass } from '@expo/eas-json';
import chalk from 'chalk';
import fs from 'fs-extra';
@@ -53,11 +53,21 @@ const EAS_JSON_MANAGED_DEFAULT: EasJson = {
development: {
developmentClient: true,
distribution: 'internal',
ios: {
resourceClass: ResourceClass.M1_MEDIUM,
},
},
preview: {
distribution: 'internal',
ios: {
resourceClass: ResourceClass.M1_MEDIUM,
},
},
production: {
ios: {
resourceClass: ResourceClass.M1_MEDIUM,
},
},
production: {},
},
submit: {
production: {},
@@ -76,12 +86,20 @@ const EAS_JSON_BARE_DEFAULT: EasJson = {
},
ios: {
buildConfiguration: 'Debug',
resourceClass: ResourceClass.M1_MEDIUM,
},
},
preview: {
distribution: 'internal',
ios: {
resourceClass: ResourceClass.M1_MEDIUM,
},
},
production: {
ios: {
resourceClass: ResourceClass.M1_MEDIUM,
},
},
production: {},
},
submit: {
production: {},
+19 -1
View File
@@ -8,8 +8,26 @@ import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '0.0.120';
export enum LocalBuildMode {
/**
* Local build that users can run on their own machines. Instead
* of sending build request to EAS Servers it's passing it as an argument
* to local-build-plugin, that will run the build locally.
*
* Triggered when running `eas build --local`.
*/
LOCAL_BUILD_PLUGIN,
/**
* Type of local build that is not accessible to users directly. When
* cloud build is triggered by git based integration, we are running
* in this mode. Instead of sending build request to EAS Servers it's
* printing it to the stdout as JSON, so EAS Build worker can read it.
*/
INTERNAL,
}
export interface LocalBuildOptions {
enable: boolean;
localBuildMode?: LocalBuildMode;
skipCleanup?: boolean;
skipNativeBuild?: boolean;
artifactsDir?: string;
@@ -221,7 +221,7 @@ export async function runBuildAndSubmitAsync(
buildCtxByPlatform[toAppPlatform(buildProfile.platform)] = buildCtx;
}
if (flags.localBuildOptions.enable) {
if (flags.localBuildOptions.localBuildMode) {
return;
}
+5 -6
View File
@@ -6,6 +6,7 @@ import figures from 'figures';
import fs from 'fs-extra';
import path from 'path';
import { LocalBuildMode } from '../../build/local';
import { BuildFlags, runBuildAndSubmitAsync } from '../../build/runBuildAndSubmit';
import EasCommand from '../../commandUtils/EasCommand';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
@@ -126,7 +127,7 @@ export default class Build extends EasCommand {
await handleDeprecatedEasJsonAsync(projectDir, flags.nonInteractive);
if (!flags.localBuildOptions.enable) {
if (!flags.localBuildOptions.localBuildMode) {
await maybeWarnAboutEasOutagesAsync(
graphqlClient,
flags.autoSubmit
@@ -194,13 +195,11 @@ export default class Build extends EasCommand {
nonInteractive,
localBuildOptions: flags['local']
? {
enable: true,
localBuildMode: LocalBuildMode.LOCAL_BUILD_PLUGIN,
verbose: true,
artifactPath: flags.output && path.resolve(process.cwd(), flags.output),
}
: {
enable: false,
},
: {},
wait: flags['wait'],
clearCache: flags['clear-cache'],
json: flags['json'],
@@ -216,7 +215,7 @@ export default class Build extends EasCommand {
): Promise<BuildFlags> {
const requestedPlatform = await selectRequestedPlatformAsync(flags.requestedPlatform);
if (flags.localBuildOptions.enable) {
if (flags.localBuildOptions.localBuildMode) {
if (flags.autoSubmit) {
// TODO: implement this
Errors.error('Auto-submits are not yet supported when building locally', { exit: 1 });
@@ -4,6 +4,7 @@ import fs from 'fs-extra';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
import { LocalBuildMode } from '../../build/local';
import { runBuildAndSubmitAsync } from '../../build/runBuildAndSubmit';
import EasCommand from '../../commandUtils/EasCommand';
import Log from '../../log';
@@ -110,7 +111,7 @@ export default class BuildInspect extends EasCommand {
requestedPlatform: flags.platform,
profile: flags.profile,
localBuildOptions: {
enable: true,
localBuildMode: LocalBuildMode.LOCAL_BUILD_PLUGIN,
...(flags.stage === InspectStage.PRE_BUILD ? { skipNativeBuild: true } : {}),
...(flags.stage === InspectStage.POST_BUILD ? { skipCleanup: true } : {}),
verbose: flags.verbose,
@@ -0,0 +1,76 @@
import { Flags } from '@oclif/core';
import { handleDeprecatedEasJsonAsync } from '.';
import { LocalBuildMode } from '../../build/local';
import { runBuildAndSubmitAsync } from '../../build/runBuildAndSubmit';
import EasCommand from '../../commandUtils/EasCommand';
import { RequestedPlatform } from '../../platform';
import { enableJsonOutput } from '../../utils/json';
/**
* This command will be run on the EAS Build workers, when building
* directly from git. This command resolves credentials and other
* build configuration, that normally would be included in the
* job and metadata objects, and prints them to stdout.
*/
export default class BuildInternal extends EasCommand {
static override hidden = true;
static override flags = {
platform: Flags.enum({
char: 'p',
options: ['android', 'ios'],
required: true,
}),
profile: Flags.string({
char: 'e',
description:
'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
helpValue: 'PROFILE_NAME',
}),
};
static override contextDefinition = {
...this.ContextOptions.LoggedIn,
...this.ContextOptions.DynamicProjectConfig,
...this.ContextOptions.ProjectDir,
...this.ContextOptions.Analytics,
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(BuildInternal);
// This command is always run with implicit --non-interactive and --json options
enableJsonOutput();
const {
loggedIn: { actor, graphqlClient },
getDynamicProjectConfigAsync,
projectDir,
analytics,
} = await this.getContextAsync(BuildInternal, {
nonInteractive: true,
});
await handleDeprecatedEasJsonAsync(projectDir, flags.nonInteractive);
await runBuildAndSubmitAsync(
graphqlClient,
analytics,
projectDir,
{
requestedPlatform: flags.platform as RequestedPlatform,
profile: flags.profile,
nonInteractive: true,
wait: false,
clearCache: false,
json: true,
autoSubmit: false,
localBuildOptions: {
localBuildMode: LocalBuildMode.INTERNAL,
},
},
actor,
getDynamicProjectConfigAsync
);
}
}
+41 -15
View File
@@ -5,10 +5,12 @@ import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { EasNonInteractiveAndJsonFlags } from '../commandUtils/flags';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log from '../log';
import { appPlatformEmojis } from '../platform';
import { selectAsync } from '../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../utils/json';
export default class Config extends EasCommand {
static override description = 'display project configuration (app.json + eas.json)';
@@ -21,6 +23,11 @@ export default class Config extends EasCommand {
'Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.',
helpValue: 'PROFILE_NAME',
}),
// This option is used only on EAS Build worker to read build profile from eas.json.
'eas-json-only': Flags.boolean({
hidden: true,
}),
...EasNonInteractiveAndJsonFlags,
};
static override contextDefinition = {
@@ -30,6 +37,9 @@ export default class Config extends EasCommand {
async runAsync(): Promise<void> {
const { flags } = await this.parse(Config);
if (flags.json) {
enableJsonOutput();
}
const { platform: maybePlatform, profile: maybeProfile } = flags;
const { getDynamicProjectConfigAsync, projectDir } = await this.getContextAsync(Config, {
nonInteractive: false,
@@ -61,21 +71,37 @@ export default class Config extends EasCommand {
]));
const profile = await EasJsonUtils.getBuildProfileAsync(accessor, platform, profileName);
const { exp: config } = await getDynamicProjectConfigAsync({
env: profile.env,
isPublicConfig: true,
});
if (flags['eas-json-only']) {
if (flags.json) {
printJsonOnlyOutput({ buildProfile: profile });
} else {
const appPlatform = toAppPlatform(platform);
const platformEmoji = appPlatformEmojis[appPlatform];
Log.log(`${platformEmoji} ${chalk.bold(`Build profile "${profileName}"`)}`);
Log.newLine();
Log.log(JSON.stringify(profile, null, 2));
}
} else {
const { exp: appConfig } = await getDynamicProjectConfigAsync({
env: profile.env,
isPublicConfig: true,
});
Log.addNewLineIfNone();
Log.log(chalk.bold(getProjectConfigDescription(projectDir)));
Log.newLine();
Log.log(JSON.stringify(config, null, 2));
Log.newLine();
Log.newLine();
const appPlatform = toAppPlatform(platform);
const platformEmoji = appPlatformEmojis[appPlatform];
Log.log(`${platformEmoji} ${chalk.bold(`Build profile "${profileName}"`)}`);
Log.newLine();
Log.log(JSON.stringify(profile, null, 2));
if (flags.json) {
printJsonOnlyOutput({ buildProfile: profile, appConfig });
} else {
Log.addNewLineIfNone();
Log.log(chalk.bold(getProjectConfigDescription(projectDir)));
Log.newLine();
Log.log(JSON.stringify(appConfig, null, 2));
Log.newLine();
Log.newLine();
const appPlatform = toAppPlatform(platform);
const platformEmoji = appPlatformEmojis[appPlatform];
Log.log(`${platformEmoji} ${chalk.bold(`Build profile "${profileName}"`)}`);
Log.newLine();
Log.log(JSON.stringify(profile, null, 2));
}
}
}
}
+2 -12
View File
@@ -39,7 +39,7 @@ export class Ignore {
if (await fs.pathExists(easIgnorePath)) {
this.ignoreMapping = [
['', createIgnore().add(DEFAULT_IGNORE)],
['', createIgnore().add(await this.readIgnoreFileAsync(easIgnorePath))],
['', createIgnore().add(await fs.readFile(easIgnorePath, 'utf-8'))],
];
return;
}
@@ -57,7 +57,7 @@ export class Ignore {
ignoreFilePaths.map(async filePath => {
return [
filePath.slice(0, filePath.length - GITIGNORE_FILENAME.length),
createIgnore().add(await this.readIgnoreFileAsync(path.join(this.rootDir, filePath))),
createIgnore().add(await fs.readFile(path.join(this.rootDir, filePath), 'utf-8')),
] as const;
})
);
@@ -72,16 +72,6 @@ export class Ignore {
}
return false;
}
private async readIgnoreFileAsync(filePath: string): Promise<string> {
const fileContents = await fs.readFile(filePath, 'utf-8');
const lines = fileContents.split('\n');
// Strip trailing '\'. This logic can be removed after fix upstream is released.
// https://github.com/kaelzhang/node-ignore/issues/81
return lines
.map((line: string) => (line.slice(-1) === '\\' ? line.slice(0, -1) : line))
.join('\n');
}
}
export async function makeShallowCopyAsync(src: string, dst: string): Promise<void> {
Generated
+450 -448
View File
File diff suppressed because it is too large. Load diff