eas-cli 0.32.0 → 0.34.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -28
- package/build/analytics.js +3 -9
- package/build/build/android/UpdatesModule.js +4 -15
- package/build/build/android/configure.js +3 -3
- package/build/build/android/graphql.js +2 -4
- package/build/build/android/prepareJob.js +4 -3
- package/build/build/build.js +2 -2
- package/build/build/configure.js +26 -13
- package/build/build/ios/UpdatesModule.js +6 -18
- package/build/build/ios/configure.js +1 -1
- package/build/build/ios/graphql.js +2 -23
- package/build/build/ios/prepareJob.js +4 -6
- package/build/build/metadata.js +5 -10
- package/build/build/utils/appJson.d.ts +1 -0
- package/build/build/utils/appJson.js +13 -4
- package/build/build/utils/devClient.d.ts +4 -4
- package/build/build/utils/devClient.js +16 -21
- package/build/build/utils/repository.js +10 -7
- package/build/build/validate.js +4 -4
- package/build/commandUtils/EasCommand.d.ts +1 -0
- package/build/commandUtils/EasCommand.js +21 -0
- package/build/commands/branch/create.js +3 -2
- package/build/commands/branch/delete.js +1 -1
- package/build/commands/branch/list.js +1 -1
- package/build/commands/branch/publish.js +20 -48
- package/build/commands/branch/view.js +1 -1
- package/build/commands/build/index.d.ts +1 -1
- package/build/commands/build/index.js +64 -49
- package/build/commands/channel/edit.js +1 -1
- package/build/commands/channel/list.js +1 -1
- package/build/commands/channel/view.js +1 -1
- package/build/commands/diagnostics.js +2 -2
- package/build/commands/project/info.js +1 -1
- package/build/commands/submit.js +15 -8
- package/build/commands/update/view.js +1 -1
- package/build/credentials/android/api/graphql/queries/GoogleServiceAccountKeyQuery.js +2 -0
- package/build/credentials/credentialsJson/update.js +5 -4
- package/build/credentials/ios/IosCredentialsProvider.js +1 -1
- package/build/credentials/ios/actions/CreateDistributionCertificate.js +1 -1
- package/build/credentials/ios/actions/CreatePushKey.js +1 -1
- package/build/credentials/ios/actions/DistributionCertificateUtils.d.ts +1 -1
- package/build/credentials/ios/actions/DistributionCertificateUtils.js +5 -7
- package/build/credentials/ios/actions/PushKeyUtils.d.ts +1 -1
- package/build/credentials/ios/actions/PushKeyUtils.js +5 -5
- package/build/credentials/ios/actions/SetupTargetBuildCredentials.js +1 -1
- package/build/credentials/ios/api/graphql/queries/AppQuery.js +3 -1
- package/build/credentials/ios/api/graphql/queries/AppleDeviceQuery.js +6 -2
- package/build/credentials/ios/api/graphql/queries/AppleDistributionCertificateQuery.js +7 -1
- package/build/credentials/ios/api/graphql/queries/AppleProvisioningProfileQuery.js +5 -1
- package/build/credentials/ios/api/graphql/queries/ApplePushKeyQuery.js +2 -0
- package/build/credentials/ios/api/graphql/queries/AppleTeamQuery.js +5 -1
- package/build/credentials/ios/utils/printCredentials.js +30 -1
- package/build/credentials/manager/Actions.d.ts +47 -0
- package/build/credentials/manager/Actions.js +48 -0
- package/build/credentials/manager/AndroidActions.d.ts +6 -0
- package/build/credentials/manager/AndroidActions.js +114 -0
- package/build/credentials/manager/IosActions.d.ts +6 -0
- package/build/credentials/manager/IosActions.js +110 -0
- package/build/credentials/manager/ManageAndroid.d.ts +1 -29
- package/build/credentials/manager/ManageAndroid.js +26 -159
- package/build/credentials/manager/ManageIos.d.ts +1 -29
- package/build/credentials/manager/ManageIos.js +28 -155
- package/build/graphql/client.d.ts +8 -2
- package/build/graphql/generated.d.ts +131 -143
- package/build/graphql/generated.js +44 -28
- package/build/graphql/queries/BuildQuery.js +4 -1
- package/build/graphql/queries/EnvironmentSecretsQuery.js +4 -2
- package/build/graphql/queries/ProjectQuery.js +3 -1
- package/build/graphql/queries/PublishQuery.js +4 -1
- package/build/graphql/queries/SubmissionQuery.js +5 -2
- package/build/graphql/queries/UserQuery.js +4 -1
- package/build/graphql/queries/WebhookQuery.js +6 -2
- package/build/graphql/types/credentials/AppStoreConnectApiKey.d.ts +1 -0
- package/build/graphql/types/credentials/AppStoreConnectApiKey.js +23 -0
- package/build/graphql/types/credentials/IosAppCredentials.js +6 -0
- package/build/log.d.ts +0 -2
- package/build/log.js +2 -12
- package/build/project/android/applicationId.d.ts +1 -1
- package/build/project/android/applicationId.js +7 -6
- package/build/project/ios/bundleIdentifier.d.ts +1 -1
- package/build/project/ios/bundleIdentifier.js +7 -6
- package/build/project/projectUtils.js +1 -1
- package/build/project/publish.js +2 -2
- package/build/project/workflow.js +2 -2
- package/build/submit/ArchiveSource.js +4 -4
- package/build/submit/ios/IosSubmitCommand.js +4 -0
- package/build/submit/ios/IosSubmitter.js +1 -1
- package/build/user/User.js +1 -0
- package/build/utils/easCli.d.ts +1 -0
- package/build/utils/easCli.js +5 -0
- package/build/utils/{expoCommand.d.ts → expoCli.d.ts} +0 -0
- package/build/utils/{expoCommand.js → expoCli.js} +0 -0
- package/build/utils/profiles.d.ts +11 -0
- package/build/utils/profiles.js +46 -0
- package/build/vcs/clients/git.d.ts +26 -0
- package/build/vcs/clients/git.js +184 -0
- package/build/vcs/clients/gitNoCommit.d.ts +7 -0
- package/build/vcs/clients/gitNoCommit.js +27 -0
- package/build/vcs/clients/noVcs.d.ts +6 -0
- package/build/vcs/clients/noVcs.js +19 -0
- package/build/vcs/git.d.ts +10 -17
- package/build/vcs/git.js +7 -175
- package/build/vcs/index.d.ts +2 -2
- package/build/vcs/index.js +15 -6
- package/build/vcs/local.d.ts +18 -5
- package/build/vcs/local.js +61 -32
- package/build/vcs/vcs.d.ts +2 -1
- package/build/vcs/vcs.js +8 -4
- package/oclif.manifest.json +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isGitCaseSensitiveAsync = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
|
|
6
|
+
const log_1 = (0, tslib_1.__importStar)(require("../../log"));
|
|
7
|
+
const prompts_1 = require("../../prompts");
|
|
8
|
+
const git_1 = require("../git");
|
|
9
|
+
const vcs_1 = require("../vcs");
|
|
10
|
+
class GitClient extends vcs_1.Client {
|
|
11
|
+
async ensureRepoExistsAsync() {
|
|
12
|
+
if (!(await (0, git_1.isGitInstalledAsync)())) {
|
|
13
|
+
throw new Error('git command not found, install it before proceeding');
|
|
14
|
+
}
|
|
15
|
+
if (await (0, git_1.doesGitRepoExistAsync)()) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
log_1.default.warn("It looks like you haven't initialized the git repository yet.");
|
|
19
|
+
log_1.default.warn('EAS Build requires you to use a git repository for your project.');
|
|
20
|
+
const confirmInit = await (0, prompts_1.confirmAsync)({
|
|
21
|
+
message: `Would you like us to run 'git init' in the current directory for you?`,
|
|
22
|
+
});
|
|
23
|
+
if (!confirmInit) {
|
|
24
|
+
throw new Error('A git repository is required for building your project. Initialize it and run this command again.');
|
|
25
|
+
}
|
|
26
|
+
await (0, spawn_async_1.default)('git', ['init']);
|
|
27
|
+
log_1.default.log("We're going to make an initial commit for your repository.");
|
|
28
|
+
const { message } = await (0, prompts_1.promptAsync)({
|
|
29
|
+
type: 'text',
|
|
30
|
+
name: 'message',
|
|
31
|
+
message: 'Commit message:',
|
|
32
|
+
initial: 'Initial commit',
|
|
33
|
+
validate: (input) => input !== '',
|
|
34
|
+
});
|
|
35
|
+
await this.commitAsync({ commitAllFiles: true, commitMessage: message });
|
|
36
|
+
}
|
|
37
|
+
async commitAsync({ commitMessage, commitAllFiles, }) {
|
|
38
|
+
if (commitAllFiles) {
|
|
39
|
+
await (0, spawn_async_1.default)('git', ['add', '-A']);
|
|
40
|
+
}
|
|
41
|
+
await (0, spawn_async_1.default)('git', ['add', '-u']);
|
|
42
|
+
await (0, spawn_async_1.default)('git', ['commit', '-m', commitMessage]);
|
|
43
|
+
}
|
|
44
|
+
async isCommitRequiredAsync() {
|
|
45
|
+
return await this.hasUncommittedChangesAsync();
|
|
46
|
+
}
|
|
47
|
+
async hasUncommittedChangesAsync() {
|
|
48
|
+
const changes = await (0, git_1.gitStatusAsync)({ showUntracked: true });
|
|
49
|
+
return changes.length > 0;
|
|
50
|
+
}
|
|
51
|
+
async getRootPathAsync() {
|
|
52
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--show-toplevel'])).stdout.trim();
|
|
53
|
+
}
|
|
54
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
55
|
+
if (await this.hasUncommittedChangesAsync()) {
|
|
56
|
+
// it should already be checked before this function is called, but in case it wasn't
|
|
57
|
+
// we want to ensure that any changes were introduced by call to `setGitCaseSensitivityAsync`
|
|
58
|
+
throw new Error('You have some uncommitted changes in your repository.');
|
|
59
|
+
}
|
|
60
|
+
let gitRepoUri;
|
|
61
|
+
if (process.platform === 'win32') {
|
|
62
|
+
// getRootDirectoryAsync() will return C:/path/to/repo on Windows and path
|
|
63
|
+
// prefix should be file:///
|
|
64
|
+
gitRepoUri = `file:///${await this.getRootPathAsync()}`;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// getRootDirectoryAsync() will /path/to/repo, and path prefix should be
|
|
68
|
+
// file:/// so only file:// needs to be prepended
|
|
69
|
+
gitRepoUri = `file://${await this.getRootPathAsync()}`;
|
|
70
|
+
}
|
|
71
|
+
const isCaseSensitive = await isGitCaseSensitiveAsync();
|
|
72
|
+
await setGitCaseSensitivityAsync(true);
|
|
73
|
+
try {
|
|
74
|
+
if (await this.hasUncommittedChangesAsync()) {
|
|
75
|
+
log_1.default.error('Detected inconsistent filename casing between your local filesystem and git.');
|
|
76
|
+
log_1.default.error('This will likely cause your build to fail. Impacted files:');
|
|
77
|
+
await (0, spawn_async_1.default)('git', ['status', '--short'], { stdio: 'inherit' });
|
|
78
|
+
log_1.default.newLine();
|
|
79
|
+
log_1.default.error(`Error: Resolve filename casing inconsistencies before proceeding. ${(0, log_1.learnMore)('https://expo.fyi/macos-ignorecase')}`);
|
|
80
|
+
throw new Error('You have some uncommitted changes in your repository.');
|
|
81
|
+
}
|
|
82
|
+
await (0, spawn_async_1.default)('git', [
|
|
83
|
+
'clone',
|
|
84
|
+
'--no-hardlinks',
|
|
85
|
+
'--depth',
|
|
86
|
+
'1',
|
|
87
|
+
gitRepoUri,
|
|
88
|
+
destinationPath,
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await setGitCaseSensitivityAsync(isCaseSensitive);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async getCommitHashAsync() {
|
|
96
|
+
try {
|
|
97
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', 'HEAD'])).stdout.trim();
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async trackFileAsync(file) {
|
|
104
|
+
await (0, spawn_async_1.default)('git', ['add', '--intent-to-add', file]);
|
|
105
|
+
}
|
|
106
|
+
async getBranchNameAsync() {
|
|
107
|
+
try {
|
|
108
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim();
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async getLastCommitMessageAsync() {
|
|
115
|
+
try {
|
|
116
|
+
return (await (0, spawn_async_1.default)('git', ['--no-pager', 'log', '-1', '--pretty=%B'])).stdout.trim();
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async showDiffAsync() {
|
|
123
|
+
const outputTooLarge = (await (0, git_1.getGitDiffOutputAsync)()).split(/\r\n|\r|\n/).length > 100;
|
|
124
|
+
await (0, git_1.gitDiffAsync)({ withPager: outputTooLarge });
|
|
125
|
+
}
|
|
126
|
+
async isFileUntrackedAsync(path) {
|
|
127
|
+
const withUntrackedFiles = await (0, git_1.gitStatusAsync)({ showUntracked: true });
|
|
128
|
+
const trackedFiles = await (0, git_1.gitStatusAsync)({ showUntracked: false });
|
|
129
|
+
const pathWithoutLeadingDot = path.replace(/^\.\//, ''); // remove leading './' from path
|
|
130
|
+
return (withUntrackedFiles.includes(pathWithoutLeadingDot) &&
|
|
131
|
+
!trackedFiles.includes(pathWithoutLeadingDot));
|
|
132
|
+
}
|
|
133
|
+
async isFileIgnoredAsync(filePath) {
|
|
134
|
+
try {
|
|
135
|
+
await (0, spawn_async_1.default)('git', ['check-ignore', '-q', filePath]);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
catch (e) {
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.default = GitClient;
|
|
144
|
+
/**
|
|
145
|
+
* Checks if git is configured to be case sensitive
|
|
146
|
+
* @returns {boolean | undefined}
|
|
147
|
+
* - boolean - is git case sensitive
|
|
148
|
+
* - undefined - case sensitivity is not configured and git is using default behavior
|
|
149
|
+
*/
|
|
150
|
+
async function isGitCaseSensitiveAsync() {
|
|
151
|
+
if (process.platform !== 'darwin') {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const result = await (0, spawn_async_1.default)('git', ['config', '--get', 'core.ignorecase']);
|
|
156
|
+
const isIgnoreCaseEnabled = result.stdout.trim();
|
|
157
|
+
if (isIgnoreCaseEnabled === '') {
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
else if (isIgnoreCaseEnabled === 'true') {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.isGitCaseSensitiveAsync = isGitCaseSensitiveAsync;
|
|
172
|
+
async function setGitCaseSensitivityAsync(enable) {
|
|
173
|
+
// we are assuming that if someone sets that on non-macos device then
|
|
174
|
+
// they know what they are doing
|
|
175
|
+
if (process.platform !== 'darwin') {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (enable === undefined) {
|
|
179
|
+
await (0, spawn_async_1.default)('git', ['config', '--unset', 'core.ignorecase']);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
await (0, spawn_async_1.default)('git', ['config', 'core.ignorecase', String(!enable)]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import GitClient from './git';
|
|
2
|
+
export default class GitNoCommitClient extends GitClient {
|
|
3
|
+
isCommitRequiredAsync(): Promise<boolean>;
|
|
4
|
+
getRootPathAsync(): Promise<string>;
|
|
5
|
+
makeShallowCopyAsync(destinationPath: string): Promise<void>;
|
|
6
|
+
isFileIgnoredAsync(filePath: string): Promise<boolean>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
|
|
5
|
+
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
6
|
+
const local_1 = require("../local");
|
|
7
|
+
const git_1 = (0, tslib_1.__importDefault)(require("./git"));
|
|
8
|
+
class GitNoCommitClient extends git_1.default {
|
|
9
|
+
async isCommitRequiredAsync() {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
async getRootPathAsync() {
|
|
13
|
+
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--show-toplevel'])).stdout.trim();
|
|
14
|
+
}
|
|
15
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
16
|
+
// normalize converts C:/some/path to C:\some\path on windows
|
|
17
|
+
const srcPath = path_1.default.normalize(await this.getRootPathAsync());
|
|
18
|
+
await (0, local_1.makeShallowCopyAsync)(srcPath, destinationPath);
|
|
19
|
+
}
|
|
20
|
+
async isFileIgnoredAsync(filePath) {
|
|
21
|
+
// normalize converts C:/some/path to C:\some\path on windows
|
|
22
|
+
const ignore = new local_1.Ignore(await this.getRootPathAsync());
|
|
23
|
+
await ignore.initIgnoreAsync();
|
|
24
|
+
return ignore.ignores(filePath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = GitNoCommitClient;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const local_1 = require("../local");
|
|
4
|
+
const vcs_1 = require("../vcs");
|
|
5
|
+
class NoVcsClient extends vcs_1.Client {
|
|
6
|
+
async getRootPathAsync() {
|
|
7
|
+
return (0, local_1.getRootPath)();
|
|
8
|
+
}
|
|
9
|
+
async makeShallowCopyAsync(destinationPath) {
|
|
10
|
+
const srcPath = (0, local_1.getRootPath)();
|
|
11
|
+
await (0, local_1.makeShallowCopyAsync)(srcPath, destinationPath);
|
|
12
|
+
}
|
|
13
|
+
async isFileIgnoredAsync(filePath) {
|
|
14
|
+
const ignore = new local_1.Ignore((0, local_1.getRootPath)());
|
|
15
|
+
await ignore.initIgnoreAsync();
|
|
16
|
+
return ignore.ignores(filePath);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.default = NoVcsClient;
|
package/build/vcs/git.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
commitMessage: string;
|
|
6
|
-
commitAllFiles?: boolean;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
hasUncommittedChangesAsync(): Promise<boolean>;
|
|
9
|
-
getRootPathAsync(): Promise<string>;
|
|
10
|
-
makeShallowCopyAsync(destinationPath: string): Promise<void>;
|
|
11
|
-
getCommitHashAsync(): Promise<string | undefined>;
|
|
12
|
-
trackFileAsync(file: string): Promise<void>;
|
|
13
|
-
getBranchNameAsync(): Promise<string | null>;
|
|
14
|
-
getLastCommitMessageAsync(): Promise<string | null>;
|
|
15
|
-
showDiffAsync(): Promise<void>;
|
|
16
|
-
isFileUntrackedAsync(path: string): Promise<boolean>;
|
|
17
|
-
isFileIgnoredAsync(filePath: string): Promise<boolean>;
|
|
1
|
+
export declare function isGitInstalledAsync(): Promise<boolean>;
|
|
2
|
+
export declare function doesGitRepoExistAsync(): Promise<boolean>;
|
|
3
|
+
interface GitStatusOptions {
|
|
4
|
+
showUntracked?: boolean;
|
|
18
5
|
}
|
|
6
|
+
export declare function gitStatusAsync({ showUntracked }?: GitStatusOptions): Promise<string>;
|
|
7
|
+
export declare function getGitDiffOutputAsync(): Promise<string>;
|
|
8
|
+
export declare function gitDiffAsync({ withPager, }?: {
|
|
9
|
+
withPager?: boolean;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
export {};
|
package/build/vcs/git.js
CHANGED
|
@@ -1,141 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gitDiffAsync = exports.getGitDiffOutputAsync = exports.gitStatusAsync = exports.doesGitRepoExistAsync = exports.isGitInstalledAsync = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const spawn_async_1 = (0, tslib_1.__importDefault)(require("@expo/spawn-async"));
|
|
5
|
-
const log_1 = (0, tslib_1.__importStar)(require("../log"));
|
|
6
|
-
const prompts_1 = require("../prompts");
|
|
7
|
-
const vcs_1 = require("./vcs");
|
|
8
|
-
class GitClient extends vcs_1.Client {
|
|
9
|
-
async ensureRepoExistsAsync() {
|
|
10
|
-
if (!(await isGitInstalledAsync())) {
|
|
11
|
-
throw new Error('git command not found, install it before proceeding');
|
|
12
|
-
}
|
|
13
|
-
if (await doesGitRepoExistAsync()) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
log_1.default.warn("It looks like you haven't initialized the git repository yet.");
|
|
17
|
-
log_1.default.warn('EAS Build requires you to use a git repository for your project.');
|
|
18
|
-
const confirmInit = await (0, prompts_1.confirmAsync)({
|
|
19
|
-
message: `Would you like to run 'git init' in the current directory?`,
|
|
20
|
-
});
|
|
21
|
-
if (!confirmInit) {
|
|
22
|
-
throw new Error('A git repository is required for building your project. Initialize it and run this command again.');
|
|
23
|
-
}
|
|
24
|
-
await (0, spawn_async_1.default)('git', ['init']);
|
|
25
|
-
log_1.default.log("We're going to make an initial commit for you repository.");
|
|
26
|
-
const { message } = await (0, prompts_1.promptAsync)({
|
|
27
|
-
type: 'text',
|
|
28
|
-
name: 'message',
|
|
29
|
-
message: 'Commit message:',
|
|
30
|
-
initial: 'Initial commit',
|
|
31
|
-
validate: (input) => input !== '',
|
|
32
|
-
});
|
|
33
|
-
await this.commitAsync({ commitAllFiles: true, commitMessage: message });
|
|
34
|
-
}
|
|
35
|
-
async commitAsync({ commitMessage, commitAllFiles, }) {
|
|
36
|
-
if (commitAllFiles) {
|
|
37
|
-
await (0, spawn_async_1.default)('git', ['add', '-A']);
|
|
38
|
-
}
|
|
39
|
-
await (0, spawn_async_1.default)('git', ['add', '-u']);
|
|
40
|
-
await (0, spawn_async_1.default)('git', ['commit', '-m', commitMessage]);
|
|
41
|
-
}
|
|
42
|
-
async hasUncommittedChangesAsync() {
|
|
43
|
-
const changes = await gitStatusAsync({ showUntracked: true });
|
|
44
|
-
return changes.length > 0;
|
|
45
|
-
}
|
|
46
|
-
async getRootPathAsync() {
|
|
47
|
-
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--show-toplevel'])).stdout.trim();
|
|
48
|
-
}
|
|
49
|
-
async makeShallowCopyAsync(destinationPath) {
|
|
50
|
-
if (await this.hasUncommittedChangesAsync()) {
|
|
51
|
-
// it should not happen, we need that to make sure that check before clone
|
|
52
|
-
// is always caused by case sensitivity
|
|
53
|
-
throw new Error('You have some uncommitted changes in your repository.');
|
|
54
|
-
}
|
|
55
|
-
let gitRepoUri;
|
|
56
|
-
if (process.platform === 'win32') {
|
|
57
|
-
// getRootDirectoryAsync() will return C:/path/to/repo on Windows and path
|
|
58
|
-
// prefix should be file:///
|
|
59
|
-
gitRepoUri = `file:///${await this.getRootPathAsync()}`;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
// getRootDirectoryAsync() will /path/to/repo, and path prefix should be
|
|
63
|
-
// file:/// so only file:// needs to be prepended
|
|
64
|
-
gitRepoUri = `file://${await this.getRootPathAsync()}`;
|
|
65
|
-
}
|
|
66
|
-
const isCaseSensitive = await isGitCaseSensitiveAsync();
|
|
67
|
-
await setGitCaseSensitivityAsync(true);
|
|
68
|
-
try {
|
|
69
|
-
if (await this.hasUncommittedChangesAsync()) {
|
|
70
|
-
log_1.default.error('Detected inconsistent filename casing between your local filesystem and git.');
|
|
71
|
-
log_1.default.error('This will likely cause your build to fail. Impacted files:');
|
|
72
|
-
await (0, spawn_async_1.default)('git', ['status', '--short'], { stdio: 'inherit' });
|
|
73
|
-
log_1.default.newLine();
|
|
74
|
-
log_1.default.error(`Error: Resolve filename casing inconsistencies before proceeding. ${(0, log_1.learnMore)('https://expo.fyi/macos-ignorecase')}`);
|
|
75
|
-
throw new Error('You have some uncommitted changes in your repository.');
|
|
76
|
-
}
|
|
77
|
-
await (0, spawn_async_1.default)('git', [
|
|
78
|
-
'clone',
|
|
79
|
-
'--no-hardlinks',
|
|
80
|
-
'--depth',
|
|
81
|
-
'1',
|
|
82
|
-
gitRepoUri,
|
|
83
|
-
destinationPath,
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
finally {
|
|
87
|
-
await setGitCaseSensitivityAsync(isCaseSensitive);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
async getCommitHashAsync() {
|
|
91
|
-
try {
|
|
92
|
-
return (await (0, spawn_async_1.default)('git', ['rev-parse', 'HEAD'])).stdout.trim();
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
return undefined;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
async trackFileAsync(file) {
|
|
99
|
-
await (0, spawn_async_1.default)('git', ['add', '--intent-to-add', file]);
|
|
100
|
-
}
|
|
101
|
-
async getBranchNameAsync() {
|
|
102
|
-
try {
|
|
103
|
-
return (await (0, spawn_async_1.default)('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout.trim();
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
async getLastCommitMessageAsync() {
|
|
110
|
-
try {
|
|
111
|
-
return (await (0, spawn_async_1.default)('git', ['--no-pager', 'log', '-1', '--pretty=%B'])).stdout.trim();
|
|
112
|
-
}
|
|
113
|
-
catch (e) {
|
|
114
|
-
return null;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async showDiffAsync() {
|
|
118
|
-
const outputTooLarge = (await getGitDiffOutputAsync()).split(/\r\n|\r|\n/).length > 100;
|
|
119
|
-
await gitDiffAsync({ withPager: outputTooLarge });
|
|
120
|
-
}
|
|
121
|
-
async isFileUntrackedAsync(path) {
|
|
122
|
-
const withUntrackedFiles = await gitStatusAsync({ showUntracked: true });
|
|
123
|
-
const trackedFiles = await gitStatusAsync({ showUntracked: false });
|
|
124
|
-
const pathWithoutLeadingDot = path.replace(/^\.\//, ''); // remove leading './' from path
|
|
125
|
-
return (withUntrackedFiles.includes(pathWithoutLeadingDot) &&
|
|
126
|
-
!trackedFiles.includes(pathWithoutLeadingDot));
|
|
127
|
-
}
|
|
128
|
-
async isFileIgnoredAsync(filePath) {
|
|
129
|
-
try {
|
|
130
|
-
await (0, spawn_async_1.default)('git', ['check-ignore', '-q', filePath]);
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
catch (e) {
|
|
134
|
-
return false;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
exports.default = GitClient;
|
|
139
6
|
async function isGitInstalledAsync() {
|
|
140
7
|
try {
|
|
141
8
|
await (0, spawn_async_1.default)('git', ['--help']);
|
|
@@ -148,6 +15,7 @@ async function isGitInstalledAsync() {
|
|
|
148
15
|
}
|
|
149
16
|
return true;
|
|
150
17
|
}
|
|
18
|
+
exports.isGitInstalledAsync = isGitInstalledAsync;
|
|
151
19
|
async function doesGitRepoExistAsync() {
|
|
152
20
|
try {
|
|
153
21
|
await (0, spawn_async_1.default)('git', ['rev-parse', '--git-dir']);
|
|
@@ -157,53 +25,17 @@ async function doesGitRepoExistAsync() {
|
|
|
157
25
|
return false;
|
|
158
26
|
}
|
|
159
27
|
}
|
|
28
|
+
exports.doesGitRepoExistAsync = doesGitRepoExistAsync;
|
|
160
29
|
async function gitStatusAsync({ showUntracked } = {}) {
|
|
161
30
|
return (await (0, spawn_async_1.default)('git', ['status', '-s', showUntracked ? '-uall' : '-uno'])).stdout;
|
|
162
31
|
}
|
|
32
|
+
exports.gitStatusAsync = gitStatusAsync;
|
|
163
33
|
async function getGitDiffOutputAsync() {
|
|
164
34
|
return (await (0, spawn_async_1.default)('git', ['--no-pager', 'diff'])).stdout;
|
|
165
35
|
}
|
|
166
|
-
|
|
36
|
+
exports.getGitDiffOutputAsync = getGitDiffOutputAsync;
|
|
37
|
+
async function gitDiffAsync({ withPager = false, } = {}) {
|
|
167
38
|
const options = withPager ? [] : ['--no-pager'];
|
|
168
39
|
await (0, spawn_async_1.default)('git', [...options, 'diff'], { stdio: ['ignore', 'inherit', 'inherit'] });
|
|
169
40
|
}
|
|
170
|
-
|
|
171
|
-
* Checks if git is configured to be case sensitive
|
|
172
|
-
* @returns {boolean | undefined}
|
|
173
|
-
* - boolean - is git case senstive
|
|
174
|
-
* - undefined - case sensitivity is not configured and git is using default behavior
|
|
175
|
-
*/
|
|
176
|
-
async function isGitCaseSensitiveAsync() {
|
|
177
|
-
if (process.platform !== 'darwin') {
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
|
-
try {
|
|
181
|
-
const result = await (0, spawn_async_1.default)('git', ['config', '--get', 'core.ignorecase']);
|
|
182
|
-
const isIgnoreCaseEnabled = result.stdout.trim();
|
|
183
|
-
if (isIgnoreCaseEnabled === '') {
|
|
184
|
-
return undefined;
|
|
185
|
-
}
|
|
186
|
-
else if (isIgnoreCaseEnabled === 'true') {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
else {
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
catch (e) {
|
|
194
|
-
return undefined;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
async function setGitCaseSensitivityAsync(enable) {
|
|
198
|
-
// we are assuming that if someone sets that on non-macos device then
|
|
199
|
-
// they know what they are doing
|
|
200
|
-
if (process.platform !== 'darwin') {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (enable === undefined) {
|
|
204
|
-
await (0, spawn_async_1.default)('git', ['config', '--unset', 'core.ignorecase']);
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
await (0, spawn_async_1.default)('git', ['config', 'core.ignorecase', String(!enable)]);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
41
|
+
exports.gitDiffAsync = gitDiffAsync;
|
package/build/vcs/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Client } from './vcs';
|
|
2
|
-
declare
|
|
3
|
-
export
|
|
2
|
+
export declare function setVcsClient(client: Client): void;
|
|
3
|
+
export declare function getVcsClient(): Client;
|
package/build/vcs/index.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getVcsClient = exports.setVcsClient = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
4
5
|
const log_1 = (0, tslib_1.__importDefault)(require("../log"));
|
|
5
|
-
const
|
|
6
|
-
const
|
|
6
|
+
const gitNoCommit_1 = (0, tslib_1.__importDefault)(require("./clients/gitNoCommit"));
|
|
7
|
+
const noVcs_1 = (0, tslib_1.__importDefault)(require("./clients/noVcs"));
|
|
7
8
|
const NO_VCS_WARNING = `Using EAS CLI without version control system is not recommended, use this mode only if you know what you are doing.`;
|
|
8
|
-
|
|
9
|
+
let vcsClient = resolveDefaultVcsClient();
|
|
10
|
+
function resolveDefaultVcsClient() {
|
|
9
11
|
if (process.env.EAS_NO_VCS) {
|
|
10
12
|
if (process.env.NODE_ENV !== 'test') {
|
|
11
13
|
log_1.default.warn(NO_VCS_WARNING);
|
|
12
14
|
}
|
|
13
|
-
return new
|
|
15
|
+
return new noVcs_1.default();
|
|
14
16
|
}
|
|
15
|
-
return new
|
|
17
|
+
return new gitNoCommit_1.default();
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
function setVcsClient(client) {
|
|
20
|
+
vcsClient = client;
|
|
21
|
+
}
|
|
22
|
+
exports.setVcsClient = setVcsClient;
|
|
23
|
+
function getVcsClient() {
|
|
24
|
+
return vcsClient;
|
|
25
|
+
}
|
|
26
|
+
exports.getVcsClient = getVcsClient;
|
package/build/vcs/local.d.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
export declare function getRootPath(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Ignore wraps the 'ignore' package to support multiple .gitignore files
|
|
4
|
+
* in subdirectories.
|
|
5
|
+
*
|
|
6
|
+
* Inconsistencies with git behavior:
|
|
7
|
+
* - if parent .gitignore has ignore rule and child has exception to that rule,
|
|
8
|
+
* file will still be ignored,
|
|
9
|
+
* - node_modules is always ignored,
|
|
10
|
+
* - if .easignore exists, .gitignore files are not used.
|
|
11
|
+
*/
|
|
12
|
+
export declare class Ignore {
|
|
13
|
+
private rootDir;
|
|
14
|
+
private ignoreMapping;
|
|
15
|
+
constructor(rootDir: string);
|
|
16
|
+
initIgnoreAsync(): Promise<void>;
|
|
17
|
+
ignores(relativePath: string): boolean;
|
|
6
18
|
}
|
|
19
|
+
export declare function makeShallowCopyAsync(src: string, dst: string): Promise<void>;
|
package/build/vcs/local.js
CHANGED
|
@@ -1,34 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeShallowCopyAsync = exports.Ignore = exports.getRootPath = void 0;
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const fast_glob_1 = (0, tslib_1.__importDefault)(require("fast-glob"));
|
|
4
6
|
const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
|
|
5
7
|
const ignore_1 = (0, tslib_1.__importDefault)(require("ignore"));
|
|
6
8
|
const path_1 = (0, tslib_1.__importDefault)(require("path"));
|
|
7
|
-
const
|
|
9
|
+
const EASIGNORE_FILENAME = '.easignore';
|
|
10
|
+
const GITIGNORE_FILENAME = '.gitignore';
|
|
8
11
|
const DEFAULT_IGNORE = `
|
|
12
|
+
.git
|
|
9
13
|
node_modules
|
|
10
14
|
`;
|
|
11
|
-
class LocalClient extends vcs_1.Client {
|
|
12
|
-
async getRootPathAsync() {
|
|
13
|
-
return getRootPath();
|
|
14
|
-
}
|
|
15
|
-
async makeShallowCopyAsync(destinationPath) {
|
|
16
|
-
const srcPath = getRootPath();
|
|
17
|
-
const ignore = await initIgnoreAsync();
|
|
18
|
-
await fs_extra_1.default.copy(srcPath, destinationPath, {
|
|
19
|
-
filter: (srcFilePath) => {
|
|
20
|
-
if (srcFilePath === srcPath) {
|
|
21
|
-
return true;
|
|
22
|
-
}
|
|
23
|
-
return !ignore.ignores(path_1.default.relative(srcPath, srcFilePath));
|
|
24
|
-
},
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
async isFileIgnoredAsync(filePath) {
|
|
28
|
-
return (await initIgnoreAsync()).ignores(filePath);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
exports.default = LocalClient;
|
|
32
15
|
function getRootPath() {
|
|
33
16
|
var _a;
|
|
34
17
|
const rootPath = (_a = process.env.EAS_PROJECT_ROOT) !== null && _a !== void 0 ? _a : process.cwd();
|
|
@@ -37,16 +20,62 @@ function getRootPath() {
|
|
|
37
20
|
}
|
|
38
21
|
return rootPath;
|
|
39
22
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
23
|
+
exports.getRootPath = getRootPath;
|
|
24
|
+
/**
|
|
25
|
+
* Ignore wraps the 'ignore' package to support multiple .gitignore files
|
|
26
|
+
* in subdirectories.
|
|
27
|
+
*
|
|
28
|
+
* Inconsistencies with git behavior:
|
|
29
|
+
* - if parent .gitignore has ignore rule and child has exception to that rule,
|
|
30
|
+
* file will still be ignored,
|
|
31
|
+
* - node_modules is always ignored,
|
|
32
|
+
* - if .easignore exists, .gitignore files are not used.
|
|
33
|
+
*/
|
|
34
|
+
class Ignore {
|
|
35
|
+
constructor(rootDir) {
|
|
36
|
+
this.rootDir = rootDir;
|
|
37
|
+
this.ignoreMapping = [];
|
|
38
|
+
}
|
|
39
|
+
async initIgnoreAsync() {
|
|
40
|
+
const easIgnorePath = path_1.default.join(this.rootDir, EASIGNORE_FILENAME);
|
|
41
|
+
if (await fs_extra_1.default.pathExists(easIgnorePath)) {
|
|
42
|
+
this.ignoreMapping = [
|
|
43
|
+
['', (0, ignore_1.default)().add(DEFAULT_IGNORE)],
|
|
44
|
+
['', (0, ignore_1.default)().add(await fs_extra_1.default.readFile(easIgnorePath, 'utf8'))],
|
|
45
|
+
];
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const ignoreFilePaths = (await (0, fast_glob_1.default)(`**/${GITIGNORE_FILENAME}`, { cwd: this.rootDir, ignore: ['node_modules'] }))
|
|
49
|
+
// ensure that parent dir is before child directories
|
|
50
|
+
.sort((a, b) => a.length - b.length && a.localeCompare(b));
|
|
51
|
+
const ignoreMapping = await Promise.all(ignoreFilePaths.map(async (filePath) => {
|
|
52
|
+
return [
|
|
53
|
+
filePath.slice(0, filePath.length - GITIGNORE_FILENAME.length),
|
|
54
|
+
(0, ignore_1.default)().add(await fs_extra_1.default.readFile(path_1.default.join(this.rootDir, filePath), 'utf8')),
|
|
55
|
+
];
|
|
56
|
+
}));
|
|
57
|
+
this.ignoreMapping = [['', (0, ignore_1.default)().add(DEFAULT_IGNORE)], ...ignoreMapping];
|
|
47
58
|
}
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
ignores(relativePath) {
|
|
60
|
+
for (const [prefix, ignore] of this.ignoreMapping) {
|
|
61
|
+
if (relativePath.startsWith(prefix) && ignore.ignores(relativePath.slice(prefix.length))) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return false;
|
|
50
66
|
}
|
|
51
|
-
return (0, ignore_1.default)().add(ignoreFile);
|
|
52
67
|
}
|
|
68
|
+
exports.Ignore = Ignore;
|
|
69
|
+
async function makeShallowCopyAsync(src, dst) {
|
|
70
|
+
const ignore = new Ignore(src);
|
|
71
|
+
await ignore.initIgnoreAsync();
|
|
72
|
+
await fs_extra_1.default.copy(src, dst, {
|
|
73
|
+
filter: (srcFilePath) => {
|
|
74
|
+
if (srcFilePath === src) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
return !ignore.ignores(path_1.default.relative(src, srcFilePath));
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
exports.makeShallowCopyAsync = makeShallowCopyAsync;
|