Skip to content

Commit 1ede881

Browse files
committed
Use async functions, and skip folder hash completetly if no ios/android folder
1 parent 06efa33 commit 1ede881

File tree

2 files changed

+53
-32
lines changed

2 files changed

+53
-32
lines changed

src/cli.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,23 @@ import {
88
red, green,
99
} from 'chalk';
1010
import {
11-
updateExpoApp, getCurrentHash,
12-
getModuleIdentity, verifyExpoApp, Platform,
13-
updateLibrary, verifyLibrary, getModulesForPlatform, isGitDirty,
11+
getCurrentHash,
12+
getModuleIdentity,
13+
getModulesForPlatform,
14+
isGitDirty,
15+
Platform,
16+
updateExpoApp,
17+
updateLibrary,
18+
verifyExpoApp,
19+
verifyLibrary,
1420
} from '.';
1521

1622
function absoluteOrRelativePath(path: string) {
1723
return path.startsWith('/') ? path : join(process.cwd(), path);
1824
}
1925

20-
const throwIfGitDirty = () => {
21-
if (isGitDirty('.')) {
26+
const throwIfGitDirty = async () => {
27+
if (await isGitDirty('.')) {
2228
console.error(red('[expo-native-dependency-hash] Git working copy is dirty. Please commit or stash your changes before running this command.'));
2329
process.exit(1);
2430
}
@@ -107,7 +113,7 @@ void yargs(hideBin(process.argv))
107113
console.log('generate', argv);
108114
}
109115

110-
if (verbose) console.info(`getting depenency hash for native dependencies in: ${rootDir}`);
116+
if (verbose) console.info(`getting dependency hash for native dependencies in: ${rootDir}`);
111117
await updateExpoApp(
112118
{
113119
rootDir,
@@ -141,7 +147,7 @@ void yargs(hideBin(process.argv))
141147
const { force } = argv;
142148

143149
if (!force) {
144-
throwIfGitDirty();
150+
await throwIfGitDirty();
145151
}
146152

147153
if (verbose) {
@@ -187,7 +193,7 @@ void yargs(hideBin(process.argv))
187193
const { force } = argv;
188194

189195
if (!force) {
190-
throwIfGitDirty();
196+
await throwIfGitDirty();
191197
}
192198

193199
const rootDir = absoluteOrRelativePath(argv.rootDir);
@@ -196,7 +202,7 @@ void yargs(hideBin(process.argv))
196202
console.log('generate', argv);
197203
}
198204

199-
if (verbose) console.info(`getting depenency hash for native dependencies in: ${rootDir}`);
205+
if (verbose) console.info(`getting dependency hash for native dependencies in: ${rootDir}`);
200206

201207
await updateLibrary(
202208
{
@@ -229,7 +235,7 @@ void yargs(hideBin(process.argv))
229235
console.log('list', argv);
230236
}
231237

232-
if (verbose) console.info(`getting depenency hash for native dependencies in: ${rootDir}`);
238+
if (verbose) console.info(`getting dependency hash for native dependencies in: ${rootDir}`);
233239

234240
const allModules = await getModulesForPlatform(platform, rootDir);
235241

@@ -269,7 +275,7 @@ void yargs(hideBin(process.argv))
269275
const { force } = argv;
270276

271277
if (!force) {
272-
throwIfGitDirty();
278+
await throwIfGitDirty();
273279
}
274280

275281
const rootDir = absoluteOrRelativePath(argv.rootDir);
@@ -278,7 +284,7 @@ void yargs(hideBin(process.argv))
278284
console.log('expo-native-dependency-hash', argv);
279285
}
280286

281-
if (verbose) console.info(`getting depenency hash for native dependencies in: ${rootDir}`);
287+
if (verbose) console.info(`getting dependency hash for native dependencies in: ${rootDir}`);
282288
const hash = await getCurrentHash(platform, {
283289
rootDir,
284290
verbose,

src/index.ts

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@ import { createHash } from 'crypto';
77
import {
88
red, green, yellow, bold,
99
} from 'chalk';
10-
import { execSync } from 'child_process';
10+
import { exec } from 'child_process';
1111
import * as Path from 'node:path';
12+
import * as util from 'util';
1213
import stableStringify from 'fast-safe-stringify';
13-
import { readFileSync } from 'fs';
1414

1515
import '@total-typescript/ts-reset';
1616

1717
import type { ExpoConfig, Android, IOS } from '@expo/config-types';
1818

19+
const execAsync = util.promisify(exec);
20+
1921
export type Module = {
2022
name: string,
2123
path: string,
@@ -86,15 +88,26 @@ export const hashFiles = async (rootDir: string, relativeFilePaths: string[], ve
8688
return hashIt(nativeFilesHashes.join(','));
8789
};
8890

89-
export const isGitDirty = (rootDir: string) => {
90-
const gitDiffOutput = execSync('git diff HEAD', { cwd: rootDir, encoding: 'utf8' }).toString();
91+
export const isGitDirty = async (rootDir: string) => {
92+
const gitDiffOutput = (await execAsync('git diff HEAD', { cwd: rootDir, encoding: 'utf8' })).stdout;
9193
return gitDiffOutput.length > 0;
9294
};
9395

9496
export const getFolderHash = async (platform: Platform, rootDir: string, verbose = false) => {
95-
const gitFiles = execSync('git ls-tree -r HEAD --name-only', { cwd: rootDir, encoding: 'utf8', env: process.env });
97+
const hasAndroidOrIOSFolders = await hasNativeVersion(platform, rootDir);
98+
99+
// if there are no native folders, we don't need to hash anything
100+
if (!hasAndroidOrIOSFolders) {
101+
return '';
102+
}
103+
104+
const gitFiles = await execAsync('git ls-tree -r HEAD --name-only', {
105+
cwd: rootDir,
106+
encoding: 'utf8',
107+
env: process.env,
108+
});
96109

97-
const nativeFiles = gitFiles
110+
const nativeFiles = gitFiles.stdout
98111
.split('\n')
99112
.filter((f) => {
100113
const includeBecauseIos = platform !== Platform.android && (f.startsWith('ios') || f.endsWith('.podspec'));
@@ -107,9 +120,9 @@ export const getFolderHash = async (platform: Platform, rootDir: string, verbose
107120
};
108121

109122
export const getAppPluginHash = async (rootDir: string, verbose = false) => {
110-
const gitFiles = execSync('git ls-tree -r HEAD --name-only', { cwd: rootDir, encoding: 'utf8', env: process.env });
123+
const gitFiles = await execAsync('git ls-tree -r HEAD --name-only', { cwd: rootDir, encoding: 'utf8', env: process.env });
111124

112-
const nativeFiles = gitFiles
125+
const nativeFiles = gitFiles.stdout
113126
.split('\n')
114127
.filter((f) => {
115128
const includeBecauseAppPlugin = f.endsWith('plugin.js') || f.endsWith('plugin.ts');
@@ -212,9 +225,9 @@ export const getModules = async (rootDir = '.') => {
212225
}
213226
};
214227

215-
export const readExpoConfig = (rootDir = '.') => {
216-
const appJsonStr = execSync('npx expo config --json --full --type prebuild', { cwd: rootDir, encoding: 'utf-8', env: process.env });
217-
const appJson = JSON.parse(appJsonStr) as { exp: ExpoConfig };
228+
export const readExpoConfig = async (rootDir = '.') => {
229+
const appJsonStr = await execAsync('npx expo config --json --full --type prebuild', { cwd: rootDir, encoding: 'utf-8', env: process.env });
230+
const appJson = JSON.parse(appJsonStr.stdout) as { exp: ExpoConfig };
218231
return appJson.exp;
219232
};
220233

@@ -255,11 +268,11 @@ const expoPropsToHash: Partial<Record<keyof ExpoConfig, boolean>> = {
255268
jsEngine: true,
256269
};
257270

258-
const getAppJsonHash = (platform = Platform.all, rootDir = '.', verbose = false) => {
271+
const getAppJsonHash = async (platform = Platform.all, rootDir = '.', verbose = false) => {
259272
let appJsonContent = '';
260273

261274
try {
262-
const appJson = readExpoConfig(rootDir);
275+
const appJson = await readExpoConfig(rootDir);
263276

264277
Object.keys(appJson || {}).forEach((key) => {
265278
if (!expoPropsToHash[key]) {
@@ -286,12 +299,14 @@ const getAppJsonHash = (platform = Platform.all, rootDir = '.', verbose = false)
286299
delete appJson.ios?.[key];
287300
} else if (key === 'entitlements') {
288301
Object.keys(appJson.ios?.entitlements || {}).forEach((entitlementKey) => {
289-
if (appJson.ios?.entitlements?.[entitlementKey]) {
302+
// eslint-disable-next-line max-len
303+
const entitlementValue = appJson.ios?.entitlements?.[entitlementKey] as string | undefined;
304+
if (entitlementValue && typeof entitlementValue === 'string' && bundleIdentifier && appJson?.ios?.entitlements) {
290305
// some entitlements have the bundleIdentifier in them,
291306
// lets ignore it to avoid unnecessary rebuilds
292307
// eslint-disable-next-line max-len
293308
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
294-
appJson.ios.entitlements[entitlementKey] = appJson.ios.entitlements[entitlementKey].replace(bundleIdentifier, '');
309+
appJson.ios.entitlements[entitlementKey] = entitlementValue.replace(bundleIdentifier, '');
295310
}
296311
});
297312
}
@@ -332,7 +347,7 @@ export const getCurrentHash = async (platform: Platform, {
332347
}: GenerateHashOptions = GENERATE_HASH_DEFAULTS) => {
333348
const localNativeFoldersHash = await getFolderHash(platform, rootDir, verbose);
334349

335-
const appJsonContent = skipAppJson ? '' : getAppJsonHash(platform, rootDir, verbose);
350+
const appJsonContent = skipAppJson ? '' : await getAppJsonHash(platform, rootDir, verbose);
336351

337352
const nativeModules = skipNodeModules ? [] : await getModulesForPlatform(platform, rootDir);
338353

@@ -380,15 +395,15 @@ export async function verifyExpoApp(
380395
rootDir: string;
381396
},
382397
) {
383-
if (verbose) { console.info(`getting depenency hash for native dependencies in: ${rootDir}`); }
398+
if (verbose) { console.info(`getting dependency hash for native dependencies in: ${rootDir}`); }
384399

385400
const { ios, android, all } = await generateHashes({ rootDir, verbose });
386401

387402
let valueExists = false;
388403
let hasChanged = false;
389404

390405
try {
391-
const expoConfig = readExpoConfig(rootDir);
406+
const expoConfig = await readExpoConfig(rootDir);
392407

393408
if (expoConfig.runtimeVersion) {
394409
valueExists = true;
@@ -441,7 +456,7 @@ export async function updateExpoApp(
441456
const { ios, android, all } = await generateHashes({ rootDir, verbose });
442457

443458
try {
444-
const fileStr = readFileSync(Path.join(rootDir, 'app.json'), 'utf8');
459+
const fileStr = await readFile(Path.join(rootDir, 'app.json'), 'utf8');
445460
const prevJson = JSON.parse(fileStr) as { expo: ExpoConfig };
446461

447462
prevJson.expo.runtimeVersion = all;
@@ -465,7 +480,7 @@ export async function verifyLibrary(
465480
rootDir: string;
466481
},
467482
) {
468-
if (verbose) { console.info(`getting depenency hash for native dependencies in: ${rootDir}`); }
483+
if (verbose) { console.info(`getting dependency hash for native dependencies in: ${rootDir}`); }
469484

470485
const { ios, android, all } = await generateHashes({
471486
rootDir, verbose, skipNodeModules: true, skipAppJson: true,

0 commit comments

Comments
 (0)