Skip to content
This repository has been archived by the owner on Jan 3, 2024. It is now read-only.

Commit

Permalink
fix: Files flag #37 (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
Maxim authored Feb 18, 2021
1 parent 7edfd5e commit 95b4db8
Show file tree
Hide file tree
Showing 15 changed files with 166 additions and 31 deletions.
5 changes: 4 additions & 1 deletion core/cli/src/commands/action-graph/actionGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ export async function run(options: ActionGraphCommandOptions) {
const actionGraph = getActionGraph({
workspace,
dependencyGraph,
task: { name: task, projects },
task: {
name: task,
projects: projects.map(project => ({ project, files: [] }))
},
lifecycle: true
});

Expand Down
2 changes: 1 addition & 1 deletion core/cli/src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ async function handler(argv: CommonOptions) {
const dependencyGraph = dependencyGraphFromWorkspace(workspace);

const projects = ((all || !projectName) && !projectNamesArg && !files
? [...workspace.projects]
? [...workspace.projects].map(project => ({ project, files: [] }))
: getProjectsByName(workspace, files || projectNames, Boolean(files))
).filter(
item =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getProjectsByName returns projects if files flag is unspecified 1`] = `
Array [
"project-a",
"project-c",
]
`;

exports[`getProjectsByName returns projects matching glob pattern 1`] = `
Array [
"project-a",
"project-b",
"project-c",
]
`;

exports[`getProjectsByName returns projects with files if files flag is specified 1`] = `
Array [
Object {
"files": Array [
"/test_path/project-a/a1.txt",
"/test_path/project-a/a2.txt",
],
"projectPath": "project-a",
},
Object {
"files": Array [
"/test_path/project-c/c2.txt",
],
"projectPath": "project-c",
},
]
`;

exports[`getProjectsByName throws if no projects are matching glob pattern 1`] = `"Projects matching \\"project-*\\" were not found"`;

exports[`getProjectsByName throws if the project name is not found 1`] = `"Project with path \\"proj-d\\" was not found"`;

exports[`getProjectsByName throws in the project containing file is not found 1`] = `"Project containing file \\"/project-X/non-existing-file.txt\\" was not found"`;
13 changes: 13 additions & 0 deletions core/garment/__tests__/fixtures/basic-workspace/garment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"projects": {
"proj-a": {
"path": "project-a"
},
"proj-b": {
"path": "project-b"
},
"proj-c": {
"path": "project-c"
}
}
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
87 changes: 87 additions & 0 deletions core/garment/__tests__/getProjectsByName.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { initFixtureHelper, replaceTestPath } from '@garment/fixture-helper';
import { Workspace } from '@garment/workspace';
import * as Path from 'path';
import { getProjectsByName } from '../src';

const { initFixture, clean } = initFixtureHelper(module, {
tempDir: Path.join(__dirname, '/tmp__')
});

const initFixtureWorkspace = async () => {
const testDir = await initFixture('basic-workspace');

const workspace = Workspace.create(
require(Path.join(testDir, 'garment.json')),
{ cwd: testDir }
);

return workspace;
};

afterAll(clean);

describe('getProjectsByName', () => {
test('returns projects if files flag is unspecified', async () => {
const workspace = await initFixtureWorkspace();

const result = getProjectsByName(workspace, ['proj-a', 'proj-c']);
expect(result.map(({ project }) => project.path)).toMatchSnapshot();
});

test('throws if the project name is not found', async () => {
const workspace = await initFixtureWorkspace();
expect(() =>
getProjectsByName(workspace, ['proj-a', 'proj-d'])
).toThrowErrorMatchingSnapshot();
});

test('returns projects with files if files flag is specified', async () => {
const workspace = await initFixtureWorkspace();

const files = [
'project-a/a1.txt',
'project-a/a2.txt',
'project-c/c2.txt'
].map(_ => workspace.resolvePath(_));

const result = getProjectsByName(workspace, files, true);
expect(
replaceTestPath(
result.map(item => ({
projectPath: item.project.path,
files: item.files
})),
workspace.cwd
)
).toMatchSnapshot();
});

test('throws in the project containing file is not found', async () => {
const workspace = await initFixtureWorkspace();
expect(() =>
getProjectsByName(
workspace,
[workspace.resolvePath('/project-X/non-existing-file.txt')],
true
)
).toThrowErrorMatchingSnapshot();
});

test('returns projects matching glob pattern', async () => {
const workspace = await initFixtureWorkspace();
try {
const result = getProjectsByName(workspace, ['proj-*']);
expect(result.map(({ project }) => project.path)).toMatchSnapshot();
} catch (error) {
console.error(error);
}
});


test('throws if no projects are matching glob pattern', async () => {
const workspace = await initFixtureWorkspace();
expect(() =>
getProjectsByName(workspace, ['project-*'])
).toThrowErrorMatchingSnapshot();
});
});
27 changes: 13 additions & 14 deletions core/garment/src/getProjectsByName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,29 @@ export function getProjectsByName(
files?: boolean
) {
const { projects } = workspace;
let result: Project[] = [];
const filesByProject = new Map<Project, string[]>();
if (files) {
projectNames.forEach(path => {
const project = projects.getByPath(path);
if (!project) {
throw new Error(`Project containing file "${path}" was not found`);
}
if (!result.includes(project)) {
result.push(project);
if (!filesByProject.has(project)) {
filesByProject.set(project, []);
}
filesByProject.get(project)!.push(path);
if (!filesByProject.has(project)) {
filesByProject.set(project, []);
}
filesByProject.get(project)!.push(path);
});
} else {
const workspaceProjectNames = projects.projectNames;
projectNames.forEach(projectName => {
if (projectName.search(/[*!]/) !== -1) {
const matchedProjects = matcher(workspaceProjectNames, [projectName]);
if (matchedProjects.length) {
result.push(...matchedProjects.map(_ => projects.get(_)!));
matchedProjects
.map(_ => projects.get(_)!)
.forEach(project => {
filesByProject.set(project, []);
});
} else {
throw new Error(`Projects matching "${projectName}" were not found`);
}
Expand All @@ -41,16 +41,15 @@ export function getProjectsByName(
project = projects.getByPathExact(workspace.resolvePath(projectName));
}
if (project) {
result.push(project);
filesByProject.set(project, []);
} else {
throw new Error(`Project with path "${projectName}" was not found`);
}
}
});
}
return result.map(project =>
filesByProject.has(project)
? { project, files: filesByProject.get(project)! }
: project
);
return [...filesByProject.entries()].map(([project, files]) => ({
project,
files
}));
}
11 changes: 5 additions & 6 deletions core/scheduler/__tests__/getActionGraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ test.skip(`actionGraph doesn't have circular dependencies`, async () => {
});
const dependencyGraph = dependencyGraphFromWorkspace(workspace);

const [app, utils] = getProjectsByName(workspace, [
'app',
'utils'
]) as Project[];
const [app, utils] = getProjectsByName(workspace, ['app', 'utils']);

const actionGraph = getActionGraph({
workspace,
Expand All @@ -25,10 +22,12 @@ test.skip(`actionGraph doesn't have circular dependencies`, async () => {
name: 'build',
projects: [
{
project: utils,
project: utils.project,
files: [__dirname + '/fixtures/basic/packages/utils/foo.txt']
},
...dependencyGraph.getDependantsOf(utils)
...dependencyGraph
.getDependantsOf(utils.project)
.map(project => ({ project, files: [] }))
]
}
});
Expand Down
11 changes: 3 additions & 8 deletions core/scheduler/src/getActionGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const getNextId = (id => () => id++)(0);

export interface ActionGraphTask {
name: string;
projects: (Project | { project: Project; files: string[] })[];
projects: { project: Project; files: string[] }[];
watch?: boolean;
}

Expand Down Expand Up @@ -55,13 +55,8 @@ export function getActionGraph(opts: GetActionGraphOptions) {

const { global = {}, ...restRunners } = runnerOptions;

for (const projectItem of projects) {
const [projectToProcess, files] =
projectItem instanceof Project
? [projectItem, undefined]
: [projectItem.project, projectItem.files];

getActionGraphByTask(name, projectToProcess, watch);
for (const { project, files } of projects) {
getActionGraphByTask(name, project, watch);

function getActionGraphByTask(
task: string,
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
"lint-staged": {
"*.{ts,tsx}": [
"prettier --write",
"eslint --fix",
"git add"
]
},
Expand Down

0 comments on commit 95b4db8

Please sign in to comment.