From 91cc2e22f2765d40f657016dd01121656449bf36 Mon Sep 17 00:00:00 2001 From: Mike Plummer Date: Mon, 27 Mar 2023 12:30:04 -0500 Subject: [PATCH] fix: Use resolved git root on Windows (#26179) --- cli/CHANGELOG.md | 1 + .../data-context/src/sources/GitDataSource.ts | 14 +++- .../test/unit/sources/GitDataSource.spec.ts | 79 ++++++++----------- renovate.json | 1 - 4 files changed, 46 insertions(+), 49 deletions(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 16e0710a8dc9..f6d38c003670 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -8,6 +8,7 @@ _Released 03/28/2023 (PENDING)_ - Fixed a compatibility issue so that component test projects can use [Vite](https://vitejs.dev/) version 4.2.0 and greater. Fixes [#26138](https://github.com/cypress-io/cypress/issues/26138). - Changed the way that Git hashes are loaded so that non-relevant runs are excluded from the Debug page. Fixes [#26058](https://github.com/cypress-io/cypress/issues/26058). - Fixed an issue where [`cy.intercept()`](https://docs.cypress.io/api/commands/intercept) added an additional `content-length` header to spied requests that did not set a `content-length` header on the original request. Fixes [#24407](https://github.com/cypress-io/cypress/issues/24407). + - Fixed an issue where an incorrect working directory could be used for Git operations on Windows. Fixes [#23317](https://github.com/cypress-io/cypress/issues/23317). **Misc:** diff --git a/packages/data-context/src/sources/GitDataSource.ts b/packages/data-context/src/sources/GitDataSource.ts index fc1a625bb914..5531bff1078c 100644 --- a/packages/data-context/src/sources/GitDataSource.ts +++ b/packages/data-context/src/sources/GitDataSource.ts @@ -96,6 +96,12 @@ export class GitDataSource { debug('exception caught when loading git client') } + // Start by assuming the git repository matches the project root + // This will be overridden if needed by the `verifyGitRepo` function + // Since that is async and we can't block the constructor we make this + // guess to avoid double-initializing + this.#gitBaseDir = this.config.projectRoot + // don't watch/refresh git data in run mode since we only // need it to detect the .git directory to set `repoRoot` if (config.isRunMode) { @@ -243,6 +249,8 @@ export class GitDataSource { debug(`Failed to watch for git changes`, e.message) this.config.onError(e) }) + + debug('Watcher initialized') } } catch (e) { this.#gitErrored = true @@ -403,9 +411,9 @@ export class GitDataSource { const cmd = `FOR %x in (${paths}) DO (${GIT_LOG_COMMAND} %x)` debug('executing command: `%s`', cmd) - debug('cwd: `%s`', this.config.projectRoot) + debug('cwd: `%s`', this.#gitBaseDir) - const subprocess = execa(cmd, { shell: true, cwd: this.config.projectRoot }) + const subprocess = execa(cmd, { shell: true, cwd: this.#gitBaseDir }) let result try { @@ -437,6 +445,8 @@ export class GitDataSource { debug('Loading git hashes') try { const logResponse = await this.#git?.log({ maxCount: 100, '--first-parent': undefined }) + + debug('hashes loaded') const currentHashes = logResponse?.all.map((log) => log.hash) if (!isEqual(this.#gitHashes, currentHashes)) { diff --git a/packages/data-context/test/unit/sources/GitDataSource.spec.ts b/packages/data-context/test/unit/sources/GitDataSource.spec.ts index 4c76e607cbcc..3dc74bc8e318 100644 --- a/packages/data-context/test/unit/sources/GitDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/GitDataSource.spec.ts @@ -1,4 +1,4 @@ -import { expect } from 'chai' +import { assert, expect } from 'chai' import path from 'path' import os from 'os' import simpleGit from 'simple-git' @@ -8,7 +8,7 @@ import pDefer from 'p-defer' import chokidar from 'chokidar' import { scaffoldMigrationProject } from '../helper' -import { GitDataSource, GitInfo } from '../../../src/sources/GitDataSource' +import { GitDataSource } from '../../../src/sources/GitDataSource' import { toPosix } from '../../../src/util/file' describe('GitDataSource', () => { @@ -21,7 +21,7 @@ describe('GitDataSource', () => { projectPath = await scaffoldMigrationProject('e2e') git = simpleGit({ baseDir: projectPath }) e2eFolder = path.join(projectPath, 'cypress', 'e2e') - const allSpecs = fs.readdirSync(e2eFolder) + const allSpecs = await fs.readdir(e2eFolder) if (process.env.CI) { // need to set a user on CI @@ -36,9 +36,9 @@ describe('GitDataSource', () => { await git.commit('add all specs') }) - afterEach(() => { + afterEach(async () => { if (gitInfo) { - gitInfo.destroy() + await gitInfo.destroy() } gitInfo = undefined @@ -46,11 +46,9 @@ describe('GitDataSource', () => { sinon.restore() }) - // TODO: fix flaky test https://github.com/cypress-io/cypress/issues/23317 - it.skip(`gets correct status for files on ${os.platform()}`, async function () { + it(`gets correct status for files on ${os.platform()}`, async function () { const onBranchChange = sinon.stub() - const onGitInfoChange = sinon.stub() - const onError = sinon.stub() + const dfd = pDefer() // create a file and modify a file to express all // git states we are interested in (created, unmodified, modified) @@ -62,28 +60,24 @@ describe('GitDataSource', () => { isRunMode: false, projectRoot: projectPath, onBranchChange, - onGitInfoChange, - onError, + onGitInfoChange: dfd.resolve, + onError: (err: any) => { + assert.fail(err) + }, }) - fs.createFileSync(fooSpec) - fs.writeFileSync(xhrSpec, 'it(\'modifies the file\', () => {})') + await fs.createFile(fooSpec) + await fs.writeFile(xhrSpec, 'it(\'modifies the file\', () => {})') gitInfo.setSpecs([fooSpec, aRecordSpec, xhrSpec]) - let result: any[] = [] - - do { - result = await Promise.all([ - gitInfo.gitInfoFor(fooSpec), - gitInfo.gitInfoFor(aRecordSpec), - gitInfo.gitInfoFor(xhrSpec), - ]) + const gitInfoChangeResolve = await dfd.promise - await new Promise((resolve) => setTimeout(resolve, 100)) - } while (result.some((r) => r == null)) + expect(gitInfoChangeResolve).to.eql([fooSpec, aRecordSpec, xhrSpec]) - const [created, unmodified, modified] = result + const created = gitInfo.gitInfoFor(fooSpec)! + const unmodified = gitInfo.gitInfoFor(aRecordSpec)! + const modified = gitInfo.gitInfoFor(xhrSpec)! expect(created.lastModifiedHumanReadable).to.match(/(a few|[0-9]) seconds? ago/) expect(created.statusType).to.eql('created') @@ -129,29 +123,27 @@ describe('GitDataSource', () => { .map((filename) => path.join(e2eFolder, filename)) .map((filepath) => toPosix(filepath)) + const dfd = pDefer() + gitInfo = new GitDataSource({ isRunMode: false, projectRoot: projectPath, onBranchChange: sinon.stub(), - onGitInfoChange: sinon.stub(), + onGitInfoChange: dfd.resolve, onError: sinon.stub(), }) - for (let filepath of filepaths) { - fs.createFileSync(filepath) - } + await Promise.all( + filepaths.map((filepath) => fs.createFile(filepath)), + ) gitInfo.setSpecs(filepaths) - let results: (GitInfo | null)[] = [] - - do { - results = await Promise.all(filepaths.map(function (filepath) { - return gitInfo.gitInfoFor(filepath) - })) + await dfd.promise - await new Promise((resolve) => setTimeout(resolve, 100)) - } while (results.some((r) => r == null)) + const results = filepaths.map((filepath) => { + return gitInfo.gitInfoFor(filepath) + }) expect(results).to.have.lengthOf(filepaths.length) @@ -217,7 +209,6 @@ describe('GitDataSource', () => { onError: errorStub, }) - await dfd.promise const result = await dfd.promise expect(result).to.eq((await git.branch()).current) @@ -226,7 +217,7 @@ describe('GitDataSource', () => { }) context('Git hashes', () => { - let clock + let clock: sinon.SinonFakeTimers beforeEach(() => { clock = sinon.useFakeTimers() @@ -239,17 +230,13 @@ describe('GitDataSource', () => { it('loads git hashes when first loaded', async () => { const dfd = pDefer() - const logCallback = () => { - dfd.resolve() - } - gitInfo = new GitDataSource({ isRunMode: false, projectRoot: projectPath, onBranchChange: sinon.stub(), onGitInfoChange: sinon.stub(), onError: sinon.stub(), - onGitLogChange: logCallback, + onGitLogChange: dfd.resolve, }) await dfd.promise @@ -281,7 +268,7 @@ describe('GitDataSource', () => { const afterCommitSpec = toPosix(path.join(e2eFolder, 'afterCommit.cy.js')) - fs.createFileSync(afterCommitSpec) + await fs.createFile(afterCommitSpec) git.add(afterCommitSpec) git.commit('add afterCommit spec') @@ -310,7 +297,7 @@ describe('GitDataSource', () => { const newSpec = toPosix(path.join(e2eFolder, 'new.cy.js')) - fs.createFileSync(newSpec) + await fs.createFile(newSpec) await git.add([newSpec]) @@ -322,7 +309,7 @@ describe('GitDataSource', () => { const featureSpec = toPosix(path.join(e2eFolder, 'feature.cy.js')) - fs.createFileSync(featureSpec) + await fs.createFile(featureSpec) await git.add([featureSpec]) await git.commit('add feature spec') diff --git a/renovate.json b/renovate.json index 33fb22e5a35e..cf880561adab 100644 --- a/renovate.json +++ b/renovate.json @@ -24,7 +24,6 @@ "schedule": [ "before 5am every weekday" ], - "packageRules": [ { "matchPackagePatterns": [