-
Notifications
You must be signed in to change notification settings - Fork 607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[rush-lib] Ignore specified files when calculating project state hash #2643
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,11 +4,13 @@ | |
import * as path from 'path'; | ||
import colors from 'colors/safe'; | ||
import * as crypto from 'crypto'; | ||
import ignore, { Ignore } from 'ignore'; | ||
|
||
import { getPackageDeps, getGitHashForFiles } from '@rushstack/package-deps-hash'; | ||
import { Path, InternalError, FileSystem } from '@rushstack/node-core-library'; | ||
import { Path, InternalError, FileSystem, Terminal, Async } from '@rushstack/node-core-library'; | ||
|
||
import { RushConfiguration } from '../api/RushConfiguration'; | ||
import { RushProjectConfiguration } from '../api/RushProjectConfiguration'; | ||
import { Git } from './Git'; | ||
import { BaseProjectShrinkwrapFile } from './base/BaseProjectShrinkwrapFile'; | ||
import { RushConfigurationProject } from '../api/RushConfigurationProject'; | ||
|
@@ -29,9 +31,12 @@ export class PackageChangeAnalyzer { | |
this._git = new Git(this._rushConfiguration); | ||
} | ||
|
||
public getPackageDeps(projectName: string): Map<string, string> | undefined { | ||
public async getPackageDeps( | ||
projectName: string, | ||
terminal: Terminal | ||
): Promise<Map<string, string> | undefined> { | ||
if (this._data === null) { | ||
this._data = this._getData(); | ||
this._data = await this._getData(terminal); | ||
} | ||
|
||
return this._data?.get(projectName); | ||
|
@@ -47,10 +52,10 @@ export class PackageChangeAnalyzer { | |
* Git SHA is fed into the hash | ||
* - A hex digest of the hash is returned | ||
*/ | ||
public getProjectStateHash(projectName: string): string | undefined { | ||
public async getProjectStateHash(projectName: string, terminal: Terminal): Promise<string | undefined> { | ||
let projectState: string | undefined = this._projectStateCache.get(projectName); | ||
if (!projectState) { | ||
const packageDeps: Map<string, string> | undefined = this.getPackageDeps(projectName); | ||
const packageDeps: Map<string, string> | undefined = await this.getPackageDeps(projectName, terminal); | ||
if (!packageDeps) { | ||
return undefined; | ||
} else { | ||
|
@@ -71,18 +76,27 @@ export class PackageChangeAnalyzer { | |
return projectState; | ||
} | ||
|
||
private _getData(): Map<string, Map<string, string>> | undefined { | ||
private async _getData(terminal: Terminal): Promise<Map<string, Map<string, string>> | undefined> { | ||
const repoDeps: Map<string, string> | undefined = this._getRepoDeps(); | ||
if (!repoDeps) { | ||
return undefined; | ||
} | ||
|
||
const projectHashDeps: Map<string, Map<string, string>> = new Map<string, Map<string, string>>(); | ||
|
||
// pre-populate the map with the projects from the config | ||
for (const project of this._rushConfiguration.projects) { | ||
projectHashDeps.set(project.packageName, new Map<string, string>()); | ||
} | ||
const ignoreMatcherForProject: Map<string, Ignore> = new Map<string, Ignore>(); | ||
|
||
// Initialize maps for each project asynchronously, up to 10 projects concurrently. | ||
await Async.forEachAsync( | ||
this._rushConfiguration.projects, | ||
async (project: RushConfigurationProject): Promise<void> => { | ||
projectHashDeps.set(project.packageName, new Map<string, string>()); | ||
ignoreMatcherForProject.set( | ||
project.packageName, | ||
await this._getIgnoreMatcherForProject(project, terminal) | ||
); | ||
}, | ||
{ concurrency: 10 } | ||
); | ||
|
||
// Sort each project folder into its own package deps hash | ||
for (const [filePath, fileHash] of repoDeps) { | ||
|
@@ -92,7 +106,14 @@ export class PackageChangeAnalyzer { | |
| RushConfigurationProject | ||
| undefined = this._rushConfiguration.findProjectForPosixRelativePath(filePath); | ||
if (owningProject) { | ||
projectHashDeps.get(owningProject.packageName)!.set(filePath, fileHash); | ||
// At this point, `filePath` is guaranteed to start with `projectRelativeFolder`, so | ||
// we can safely slice off the first N characters to get the file path relative to the | ||
// root of the `owningProject`. | ||
const relativePath: string = filePath.slice(owningProject.projectRelativeFolder.length + 1); | ||
const ignoreMatcher: Ignore | undefined = ignoreMatcherForProject.get(owningProject.packageName); | ||
if (!ignoreMatcher || !ignoreMatcher.ignores(relativePath)) { | ||
projectHashDeps.get(owningProject.packageName)!.set(filePath, fileHash); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -157,6 +178,22 @@ export class PackageChangeAnalyzer { | |
return projectHashDeps; | ||
} | ||
|
||
private async _getIgnoreMatcherForProject( | ||
project: RushConfigurationProject, | ||
terminal: Terminal | ||
): Promise<Ignore> { | ||
const projectConfiguration: | ||
| RushProjectConfiguration | ||
| undefined = await RushProjectConfiguration.tryLoadForProjectAsync(project, undefined, terminal); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Ideally this should be cached somewhere, but we don't need to solve that in this PR.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we want to do that here; this is a wrapper for the (I did file a related ticket, #2691, that will improve the caching further.) |
||
const ignoreMatcher: Ignore = ignore(); | ||
|
||
if (projectConfiguration && projectConfiguration.incrementalBuildIgnoredGlobs) { | ||
ignoreMatcher.add(projectConfiguration.incrementalBuildIgnoredGlobs); | ||
} | ||
|
||
return ignoreMatcher; | ||
} | ||
|
||
private _getRepoDeps(): Map<string, string> | undefined { | ||
try { | ||
if (this._git.isPathUnderGitWorkingTree()) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This repo uses a suffix to indicate async methods, so generally a function like this should be renamed to
getPackageDepsAsync()
when converting. The same applies to other functions modified by this same PR.