Skip to content

Commit

Permalink
Use Git to resolve root path in no-VCS mode
Browse files Browse the repository at this point in the history
  • Loading branch information
sjchmiela committed Feb 11, 2025
1 parent 574bde9 commit 5a4e36c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 12 deletions.
44 changes: 44 additions & 0 deletions packages/eas-cli/src/vcs/clients/__tests__/noVcs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import spawnAsync from '@expo/spawn-async';
import fs from 'fs/promises';
import os from 'os';
import path from 'path';

import NoVcsClient from '../noVcs';

describe('noVcs', () => {
describe('NoVcsClient', () => {
let vcs: NoVcsClient;
let repoRoot: string;
let globalEasProjectRoot: string | undefined;

afterAll(async () => {
await fs.rm(repoRoot, { recursive: true, force: true });
process.env.EAS_PROJECT_ROOT = globalEasProjectRoot;
});

beforeAll(async () => {
repoRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'eas-cli-git-test-'));

vcs = new NoVcsClient({ cwdOverride: repoRoot });
globalEasProjectRoot = process.env.EAS_PROJECT_ROOT;
delete process.env.EAS_PROJECT_ROOT;
});

it('should return the current working directory when not in Git repository', async () => {
expect(await vcs.getRootPathAsync()).toBe(process.cwd());
});

it('should return the Git root when in Git repository', async () => {
await spawnAsync('git', ['init'], { cwd: repoRoot });
expect(await fs.realpath(await vcs.getRootPathAsync())).toBe(await fs.realpath(repoRoot));
});

it('should return the project root when EAS_PROJECT_ROOT is set', async () => {
process.env.EAS_PROJECT_ROOT = 'project-root';
expect(await vcs.getRootPathAsync()).toBe(path.resolve(process.cwd(), 'project-root'));

process.env.EAS_PROJECT_ROOT = '/app';
expect(await vcs.getRootPathAsync()).toBe('/app');
});
});
});
43 changes: 39 additions & 4 deletions packages/eas-cli/src/vcs/clients/noVcs.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,53 @@
import { Ignore, getRootPath, makeShallowCopyAsync } from '../local';
import spawnAsync from '@expo/spawn-async';
import path from 'path';

import Log from '../../log';
import { Ignore, makeShallowCopyAsync } from '../local';
import { Client } from '../vcs';

export default class NoVcsClient extends Client {
private readonly cwdOverride?: string;

constructor(options: { cwdOverride?: string } = {}) {
super();
this.cwdOverride = options.cwdOverride;
}

public async getRootPathAsync(): Promise<string> {
return getRootPath();
// Honor `EAS_PROJECT_ROOT` if it is set.
if (process.env.EAS_PROJECT_ROOT) {
const rootPath = process.env.EAS_PROJECT_ROOT;
// `path.resolve()` will return `rootPath` if it is absolute
// (which is what we want).
return path.resolve(process.cwd(), rootPath);
}

// If `EAS_PROJECT_ROOT` is not set, try to get the root path from Git.
try {
return (
await spawnAsync('git', ['rev-parse', '--show-toplevel'], {
cwd: this.cwdOverride,
})
).stdout.trim();
} catch (err) {
Log.warn(`Failed to get Git root path with \`git rev-parse --show-toplevel\`.`, err);
Log.warn('Falling back to using current working directory as project root.');
Log.warn(
'You can set `EAS_PROJECT_ROOT` environment variable to let eas-cli know where your project is located.'
);

return process.cwd();
}
}

public async makeShallowCopyAsync(destinationPath: string): Promise<void> {
const srcPath = getRootPath();
const srcPath = path.normalize(await this.getRootPathAsync());
await makeShallowCopyAsync(srcPath, destinationPath);
}

public override async isFileIgnoredAsync(filePath: string): Promise<boolean> {
const ignore = await Ignore.createAsync(getRootPath());
const rootPath = path.normalize(await this.getRootPathAsync());
const ignore = await Ignore.createAsync(rootPath);
return ignore.ignores(filePath);
}

Expand Down
8 changes: 0 additions & 8 deletions packages/eas-cli/src/vcs/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,6 @@ const DEFAULT_IGNORE = `
node_modules
`;

export function getRootPath(): string {
const rootPath = process.env.EAS_PROJECT_ROOT ?? process.cwd();
if (!path.isAbsolute(rootPath)) {
return path.resolve(process.cwd(), rootPath);
}
return rootPath;
}

/**
* Ignore wraps the 'ignore' package to support multiple .gitignore files
* in subdirectories.
Expand Down

0 comments on commit 5a4e36c

Please sign in to comment.