Skip to content

Commit

Permalink
Merge pull request #4451 from iclanton/fix-deploy-folder
Browse files Browse the repository at this point in the history
[package-extractor] Fix an issue with the 'folderToCopy' option.
  • Loading branch information
iclanton authored Dec 11, 2023
2 parents a3fe769 + 840f301 commit dc7e146
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 63 deletions.
10 changes: 10 additions & 0 deletions common/changes/@microsoft/rush/main_2023-12-11-23-29.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@microsoft/rush",
"comment": "Fix an issue where the contents of a folder set in the `\"folderToCopy\"` field of the `deploy.json` config file would be copied into a subfolder instead of into the root of the deploy folder.",
"type": "none"
}
],
"packageName": "@microsoft/rush"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@rushstack/package-extractor",
"comment": "Fix an issue with the `folderToCopy` option, where the folder contents would be copied into a subfolder instead of into the target folder root.",
"type": "patch"
}
],
"packageName": "@rushstack/package-extractor"
}
17 changes: 6 additions & 11 deletions libraries/package-extractor/src/PackageExtractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ export class PackageExtractor {
mainProjectName,
sourceRootFolder,
targetRootFolder,
folderToCopy: addditionalFolderToCopy,
folderToCopy: additionalFolderToCopy,
linkCreation
} = options;
const { projectConfigurationsByName, foldersToCopy, symlinkAnalyzer } = state;
Expand Down Expand Up @@ -409,19 +409,14 @@ export class PackageExtractor {
}
);

if (addditionalFolderToCopy) {
// Copy the additional folder directly into the root of the target folder by postfixing the
// folder name to the target folder and setting the sourceRootFolder to the root of the
// folderToCopy
const additionalFolderPath: string = path.resolve(sourceRootFolder, addditionalFolderToCopy);
const targetFolderPath: string = path.join(
options.targetRootFolder,
path.basename(additionalFolderPath)
);
if (additionalFolderToCopy) {
// Copy the additional folder directly into the root of the target folder by setting the sourceRootFolder
// to the root of the folderToCopy
const additionalFolderPath: string = path.resolve(sourceRootFolder, additionalFolderToCopy);
const additionalFolderExtractorOptions: IExtractorOptions = {
...options,
sourceRootFolder: additionalFolderPath,
targetRootFolder: targetFolderPath
targetRootFolder: options.targetRootFolder
};
await this._extractFolderAsync(additionalFolderPath, additionalFolderExtractorOptions, state);
}
Expand Down
141 changes: 89 additions & 52 deletions libraries/package-extractor/src/test/PackageExtractor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,22 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(true);

// Validate project 2 is linked through node_modules
const project1NodeModulesPath: string = path.join(targetFolder, project1RelativePath, 'node_modules');
expect(
FileSystem.getRealPath(path.join(project1NodeModulesPath, project2PackageName, 'src', 'index.js'))
).toEqual(path.join(targetFolder, project2RelativePath, 'src', 'index.js'));
await expect(
FileSystem.getRealPathAsync(path.join(project1NodeModulesPath, project2PackageName, 'src', 'index.js'))
).resolves.toEqual(path.join(targetFolder, project2RelativePath, 'src', 'index.js'));

// Validate project 3 is linked through node_modules
expect(
FileSystem.getRealPath(path.join(project1NodeModulesPath, project3PackageName, 'src', 'index.js'))
).toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
expect(
FileSystem.getRealPath(
await expect(
FileSystem.getRealPathAsync(path.join(project1NodeModulesPath, project3PackageName, 'src', 'index.js'))
).resolves.toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
await expect(
FileSystem.getRealPathAsync(
path.join(
project1NodeModulesPath,
project2PackageName,
Expand All @@ -85,7 +87,7 @@ describe(PackageExtractor.name, () => {
'index.js'
)
)
).toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
).resolves.toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
});

it('should extract project with dependencies only', async () => {
Expand All @@ -107,18 +109,22 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(true);

// Validate project 2 is linked through node_modules
const project1NodeModulesPath: string = path.join(targetFolder, project1RelativePath, 'node_modules');
expect(
FileSystem.getRealPath(path.join(project1NodeModulesPath, project2PackageName, 'src', 'index.js'))
).toEqual(path.join(targetFolder, project2RelativePath, 'src', 'index.js'));
await expect(
FileSystem.getRealPathAsync(path.join(project1NodeModulesPath, project2PackageName, 'src', 'index.js'))
).resolves.toEqual(path.join(targetFolder, project2RelativePath, 'src', 'index.js'));

// Validate project 3 is not linked through node_modules on project 1 but is linked through node_modules on project 2
expect(FileSystem.exists(path.join(project1NodeModulesPath, project3PackageName))).toBe(false);
expect(
FileSystem.getRealPath(
await expect(
FileSystem.existsAsync(path.join(project1NodeModulesPath, project3PackageName))
).resolves.toBe(false);
await expect(
FileSystem.getRealPathAsync(
path.join(
project1NodeModulesPath,
project2PackageName,
Expand All @@ -128,7 +134,7 @@ describe(PackageExtractor.name, () => {
'index.js'
)
)
).toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
).resolves.toEqual(path.join(targetFolder, project3RelativePath, 'src', 'index.js'));
});

it('should throw error if main project does not exist', async () => {
Expand Down Expand Up @@ -203,13 +209,23 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(false);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'subdir'))).toBe(false);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'package.json'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(false);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'subdir'))
).resolves.toBe(false);

// Validate project 2 files
expect(FileSystem.exists(path.join(targetFolder, project2RelativePath, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project2RelativePath, 'src', 'index.js'))).toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project2RelativePath, 'package.json'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project2RelativePath, 'src', 'index.js'))
).resolves.toBe(true);
});

it('should include specified dependencies', async () => {
Expand Down Expand Up @@ -237,13 +253,21 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'package.json'))).toBe(false);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(false);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'subdir'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'subdir', 'file.js'))).toBe(
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'package.json'))
).resolves.toBe(false);
await expect(FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src'))).resolves.toBe(
true
);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(false);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'subdir'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'subdir', 'file.js'))
).resolves.toBe(true);
});

it('should exclude specified dependencies on local dependencies', async () => {
Expand Down Expand Up @@ -279,12 +303,20 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'package.json'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(true);

// Validate project 2 files
expect(FileSystem.exists(path.join(targetFolder, project2RelativePath, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project2RelativePath, 'src', 'index.js'))).toBe(false);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project2RelativePath, 'package.json'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project2RelativePath, 'src', 'index.js'))
).resolves.toBe(false);
});

it('should exclude specified files on third party dependencies with semver version', async () => {
Expand Down Expand Up @@ -325,21 +357,23 @@ describe(PackageExtractor.name, () => {
})
).resolves.not.toThrow();
// Validate project 1 files
expect(
FileSystem.exists(
await expect(
FileSystem.existsAsync(
path.join(targetFolder, project1RelativePath, 'node_modules/@types/node/fs/promises.d.ts')
)
).toBe(false);
expect(
FileSystem.exists(path.join(targetFolder, project1RelativePath, 'node_modules/@types/node/path.d.ts'))
).toBe(true);
).resolves.toBe(false);
await expect(
FileSystem.existsAsync(
path.join(targetFolder, project1RelativePath, 'node_modules/@types/node/path.d.ts')
)
).resolves.toBe(true);

// Validate project 3 files
expect(
FileSystem.exists(
await expect(
FileSystem.existsAsync(
path.join(targetFolder, project3RelativePath, 'node_modules/@types/node/fs/promises.d.ts')
)
).toBe(true);
).resolves.toBe(true);
});
it('should not exclude specified files on third party dependencies if semver version not match', async () => {
const targetFolder: string = path.join(extractorTargetFolder, 'extractor-output-08');
Expand Down Expand Up @@ -379,18 +413,18 @@ describe(PackageExtractor.name, () => {
})
).resolves.not.toThrow();
// Validate project 1 files
expect(
FileSystem.exists(
await expect(
FileSystem.existsAsync(
path.join(targetFolder, project1RelativePath, 'node_modules/@types/node/fs/promises.d.ts')
)
).toBe(true);
).resolves.toBe(true);

// Validate project file that shouldn't be exclude
expect(
FileSystem.exists(
await expect(
FileSystem.existsAsync(
path.join(targetFolder, project3RelativePath, 'node_modules/@types/node/fs/promises.d.ts')
)
).toBe(true);
).resolves.toBe(true);
});

it('should include folderToCopy', async () => {
Expand Down Expand Up @@ -418,12 +452,15 @@ describe(PackageExtractor.name, () => {
).resolves.not.toThrow();

// Validate project 1 files
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))).toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'package.json'))
).resolves.toBe(true);
await expect(
FileSystem.existsAsync(path.join(targetFolder, project1RelativePath, 'src', 'index.js'))
).resolves.toBe(true);

// Validate project 2 files
const project2FolderName: string = path.basename(project2Path);
expect(FileSystem.exists(path.join(targetFolder, project2FolderName, 'package.json'))).toBe(true);
expect(FileSystem.exists(path.join(targetFolder, project2FolderName, 'src', 'index.js'))).toBe(true);
await expect(FileSystem.existsAsync(path.join(targetFolder, 'package.json'))).resolves.toBe(true);
await expect(FileSystem.existsAsync(path.join(targetFolder, 'src', 'index.js'))).resolves.toBe(true);
});
});

0 comments on commit dc7e146

Please sign in to comment.