making filterpackage do intersection rather than union. adding tests

This commit is contained in:
Ken Chau 2020-06-18 16:40:04 -07:00
Родитель 6ec80980fc
Коммит 8ecc7d8751
7 изменённых файлов: 194 добавлений и 40 удалений

7
jasmine.json Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"spec_dir": "src/tests",
"spec_files": ["**/*[tT]est.ts"],
"helpers": ["helpers/**/*.ts"],
"oneFailurePerSpec": false,
"random": true
}

Просмотреть файл

@ -20,7 +20,11 @@
"release": "beachball publish -y",
"release:docs": "yarn docs:build && yarn gh-pages -d docs/.vuepress/dist --dotfiles",
"start": "tsc -w --preserveWatchOutput",
"test": "echo hello"
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json"
},
"resolutions": {
"mermaid": "8.5.0",
"watchpack": "1.6.1"
},
"dependencies": {
"@microsoft/task-scheduler": "^2.1.3",
@ -30,8 +34,8 @@
"backfill-logger": "^5.0.0",
"chalk": "^4.0.0",
"cosmiconfig": "^6.0.0",
"git-url-parse": "^11.1.2",
"fast-glob": "^3.2.2",
"git-url-parse": "^11.1.2",
"npmlog": "^4.1.2",
"p-profiler": "^0.1.2",
"p-queue": "^6.4.0",
@ -42,18 +46,17 @@
"@types/chalk": "^2.2.0",
"@types/cosmiconfig": "^6.0.0",
"@types/git-url-parse": "^9.0.0",
"@types/jasmine": "^3.5.10",
"@types/node": "^13.13.2",
"@types/npmlog": "^4.1.2",
"@types/p-queue": "^3.2.1",
"@types/yargs-parser": "^15.0.0",
"beachball": "^1.31.4",
"gh-pages": "^2.2.0",
"jasmine": "^3.5.0",
"ts-node": "^8.10.2",
"typescript": "^3.8.3",
"vuepress": "1.5.0",
"vuepress-plugin-mermaidjs": "1.5.1"
},
"resolutions": {
"watchpack": "1.6.1",
"mermaid": "8.5.0"
}
}

Просмотреть файл

@ -1,43 +1,24 @@
import {
getTransitiveDependencies,
getScopedPackages,
getChangedPackages,
PackageInfos,
} from "workspace-tools";
import { getTransitiveDependencies, PackageInfos } from "workspace-tools";
import { logger } from "../logger";
export function filterPackages(options: {
root: string;
allPackages: PackageInfos;
deps: boolean;
scope?: string[];
since?: string;
ignore?: string[];
scopedPackages: string[] | undefined;
changedPackages: string[] | undefined;
}) {
const { since, scope, allPackages, deps, root, ignore } = options;
const { scopedPackages, changedPackages, allPackages, deps } = options;
let filtered: string[] = [];
let hasScopes = Array.isArray(scope) && scope.length > 0;
let hasSince = typeof since !== "undefined";
// If NOTHING is specified, use all packages
if (!hasScopes && !hasSince) {
logger.verbose("filterPackages", "scope: all packages");
filtered = Object.keys(allPackages);
}
let filtered = Object.keys(allPackages);
// If scoped is defined, get scoped packages
if (hasScopes) {
const scoped = getScopedPackages(scope!, allPackages);
filtered = filtered.concat(scoped);
logger.verbose("filterPackages", `scope: ${scoped.join(",")}`);
if (typeof scopedPackages !== "undefined") {
filtered = filtered.filter((pkg) => scopedPackages.includes(pkg));
logger.verbose("filterPackages", `scope: ${scopedPackages.join(",")}`);
}
if (hasSince) {
const changedPackages = getChangedPackages(root, since, ignore);
filtered = filtered.concat(changedPackages);
if (typeof changedPackages !== "undefined") {
filtered = filtered.filter((pkg) => changedPackages.includes(pkg));
logger.verbose("filterPackages", `changed: ${changedPackages.join(",")}`);
}

Просмотреть файл

@ -5,6 +5,7 @@ import { npmTask } from "./npmTask";
import { filterPackages } from "./filterPackages";
import { Workspace } from "../types/Workspace";
import { setTaskLogMaxLengths } from "../logger";
import { getScopedPackages, getChangedPackages } from "workspace-tools";
export async function runTasks(options: {
graph: TopologicalGraph;
@ -52,13 +53,26 @@ export async function runTasks(options: {
}
// Filter packages per --scope and command(s)
const { scope, since } = config;
// If scoped is defined, get scoped packages
const hasScopes = Array.isArray(scope) && scope.length > 0;
let scopedPackages: string[] | undefined = undefined;
if (hasScopes) {
scopedPackages = getScopedPackages(scope!, workspace.allPackages);
}
const hasSince = typeof since !== "undefined";
let changedPackages: string[] | undefined = undefined;
if (hasSince) {
changedPackages = getChangedPackages(workspace.root, since, config.ignore);
}
const filteredPackages = filterPackages({
root: workspace.root,
allPackages: workspace.allPackages,
deps: config.deps,
scope: config.scope,
since: config.since,
ignore: config.ignore,
scopedPackages,
changedPackages,
});
// Set up the longest names of tasks and scripts for nice logging

Просмотреть файл

@ -0,0 +1,97 @@
import { filterPackages } from "../task/filterPackages";
import { PackageInfos, PackageInfo } from "workspace-tools";
describe("filterPackages", () => {
it("intersecting scope and since with no overlap yields no packages", () => {
const allPackages: PackageInfos = {
foo: stubPackage("foo"),
bar: stubPackage("bar"),
};
const scopedPackages = ["foo"];
const changedPackages = ["bar"];
const filtered = filterPackages({
allPackages,
deps: false,
changedPackages,
scopedPackages,
});
expect(filtered.length).toBe(0);
});
it("changed and scoped should yield intersection", () => {
const allPackages: PackageInfos = {
foo1: stubPackage("foo1"),
foo2: stubPackage("foo2"),
};
const scopedPackages = ["foo1", "foo2"];
const changedPackages = ["foo1"];
const filtered = filterPackages({
allPackages,
deps: false,
changedPackages,
scopedPackages,
});
expect(filtered).toContain("foo1");
expect(filtered).not.toContain("foo2");
});
it("changed dependencies should yield intersection of none if the scope does not contain it", () => {
const allPackages: PackageInfos = {
foo1: stubPackage("foo1", ["bar"]),
foo2: stubPackage("foo2"),
bar: stubPackage("bar"),
};
const scopedPackages = ["foo2"];
const changedPackages = ["bar"];
const filtered = filterPackages({
allPackages,
deps: false,
changedPackages,
scopedPackages,
});
expect(filtered).not.toContain("foo1");
expect(filtered).not.toContain("foo2");
expect(filtered).not.toContain("bar");
});
it("scoped will get its dependencies through the deps parameter", () => {
const allPackages: PackageInfos = {
foo1: stubPackage("foo1", ["bar"]),
foo2: stubPackage("foo2"),
bar: stubPackage("bar"),
};
const scopedPackages = ["bar"];
const changedPackages = undefined;
const filtered = filterPackages({
allPackages,
deps: true,
changedPackages,
scopedPackages,
});
expect(filtered).toContain("foo1");
expect(filtered).not.toContain("foo2");
expect(filtered).toContain("bar");
});
});
function stubPackage(name: string, deps: string[] = []) {
return {
name,
packageJsonPath: `packages/${name}`,
version: "1.0",
dependencies: deps.reduce((depMap, dep) => ({ ...depMap, [dep]: "*" }), {}),
devDependencies: {},
} as PackageInfo;
}

Просмотреть файл

@ -1,4 +1,7 @@
{
"ts-node": {
"transpileOnly": true
},
"compilerOptions": {
"target": "es2017",
"module": "commonjs",

Просмотреть файл

@ -1070,6 +1070,11 @@
"@types/minimatch" "*"
"@types/node" "*"
"@types/jasmine@^3.5.10":
version "3.5.10"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.10.tgz#a1a41012012b5da9d4b205ba9eba58f6cce2ab7b"
integrity sha512-3F8qpwBAiVc5+HPJeXJpbrl+XjawGmciN5LgiO7Gv1pl1RHtjoMNqZpqEksaPJW05ViKe8snYInRs6xB25Xdew==
"@types/minimatch@*", "@types/minimatch@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
@ -1694,6 +1699,11 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -3533,6 +3543,11 @@ diacritics@^1.3.0:
resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1"
integrity sha1-PvqHMj67hj5mls67AILUj/PW96E=
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@ -5413,6 +5428,19 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
jasmine-core@~3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.5.0.tgz#132c23e645af96d85c8bca13c8758b18429fc1e4"
integrity sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==
jasmine@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.5.0.tgz#7101eabfd043a1fc82ac24e0ab6ec56081357f9e"
integrity sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==
dependencies:
glob "^7.1.4"
jasmine-core "~3.5.0"
javascript-stringify@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-1.6.0.tgz#142d111f3a6e3dae8f4a9afd77d45855b5a9cce3"
@ -5787,6 +5815,11 @@ make-dir@^3.0.0:
dependencies:
semver "^6.0.0"
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
map-cache@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
@ -8055,7 +8088,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2:
source-map-url "^0.4.0"
urix "^0.1.0"
source-map-support@~0.5.12:
source-map-support@^0.5.17, source-map-support@~0.5.12:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@ -8657,6 +8690,17 @@ try-to-catch@^1.0.2:
resolved "https://registry.yarnpkg.com/try-to-catch/-/try-to-catch-1.1.1.tgz#770162dd13b9a0e55da04db5b7f888956072038a"
integrity sha512-ikUlS+/BcImLhNYyIgZcEmq4byc31QpC+46/6Jm5ECWkVFhf8SM2Fp/0pMVXPX6vk45SMCwrP4Taxucne8I0VA==
ts-node@^8.10.2:
version "8.10.2"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.10.2.tgz#eee03764633b1234ddd37f8db9ec10b75ec7fb8d"
integrity sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==
dependencies:
arg "^4.1.0"
diff "^4.0.1"
make-error "^1.1.1"
source-map-support "^0.5.17"
yn "3.1.1"
tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
@ -9495,6 +9539,11 @@ yargs@^15.0.2:
y18n "^4.0.0"
yargs-parser "^18.1.1"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
z-schema@~3.18.3:
version "3.18.4"
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.18.4.tgz#ea8132b279533ee60be2485a02f7e3e42541a9a2"