knip 0.0.0-graph.0 → 0.0.0-graph.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -38,6 +38,11 @@ export declare class ConfigurationChief {
38
38
  init(): Promise<void>;
39
39
  getCompilers(): [SyncCompilers, AsyncCompilers];
40
40
  getRules(): import("./types/issues.js").Rules;
41
+ getFilters(): {
42
+ dir: string;
43
+ } | {
44
+ dir?: undefined;
45
+ };
41
46
  private normalize;
42
47
  private setWorkspaces;
43
48
  private getListedWorkspaces;
@@ -103,6 +103,11 @@ export class ConfigurationChief {
103
103
  getRules() {
104
104
  return this.config.rules;
105
105
  }
106
+ getFilters() {
107
+ if (this.workspacesGraph?.graph && workspaceArg)
108
+ return { dir: join(this.cwd, workspaceArg) };
109
+ return {};
110
+ }
106
111
  normalize(rawLocalConfig) {
107
112
  const initialWorkspaces = rawLocalConfig.workspaces ?? {
108
113
  [ROOT_WORKSPACE_NAME]: {
@@ -239,23 +244,31 @@ export class ConfigurationChief {
239
244
  return ancestors;
240
245
  };
241
246
  const workspaceNames = workspaceArg
242
- ? [
243
- ...this.availableWorkspaceNames.reduce(getAncestors(workspaceArg), []),
244
- ...this.availableWorkspaceNames.filter(name => name === workspaceArg),
245
- ]
247
+ ? [...this.availableWorkspaceNames.reduce(getAncestors(workspaceArg), []), workspaceArg]
246
248
  : this.availableWorkspaceNames;
247
- const graph = this.workspacesGraph;
248
- function getDeps(dir) {
249
- const node = graph?.graph[dir];
250
- return [dir, ...(node?.dependencies ?? []), ...(node?.dependencies.flatMap(getDeps) ?? [])];
249
+ const graph = this.workspacesGraph?.graph;
250
+ const ws = new Set();
251
+ if (graph && workspaceArg) {
252
+ const seen = new Set();
253
+ const initialWorkspaces = new Set(workspaceNames.map(name => join(this.cwd, name)));
254
+ const workspaceDirsWithDependants = new Set(initialWorkspaces);
255
+ const addDependents = (dir) => {
256
+ seen.add(dir);
257
+ const deps = graph[dir]?.dependencies ?? [];
258
+ if (deps.length > 0 && Array.from(initialWorkspaces).some(dir => deps.includes(dir))) {
259
+ workspaceDirsWithDependants.add(dir);
260
+ }
261
+ deps.filter(dir => !seen.has(dir)).forEach(addDependents);
262
+ };
263
+ this.availableWorkspaceNames.map(name => join(this.cwd, name)).forEach(addDependents);
264
+ workspaceDirsWithDependants.forEach(dir => ws.add(relative(this.cwd, dir) || ROOT_WORKSPACE_NAME));
251
265
  }
252
- const workspaceNamesWithDependencies = workspaceArg
253
- ? compact(workspaceNames
254
- .map(name => join(this.cwd, name))
255
- .flatMap(getDeps)
256
- .map(dir => relative(this.cwd, dir)))
257
- : workspaceNames;
258
- return workspaceNamesWithDependencies.sort(byPathDepth).map((name) => {
266
+ else {
267
+ workspaceNames.forEach(name => ws.add(name));
268
+ }
269
+ return Array.from(ws)
270
+ .sort(byPathDepth)
271
+ .map((name) => {
259
272
  const dir = join(this.cwd, name);
260
273
  return {
261
274
  name,
@@ -1,16 +1,21 @@
1
1
  import type { ConfigurationHint, Issue, Rules } from './types/issues.js';
2
+ type Filters = Partial<{
3
+ dir: string;
4
+ }>;
2
5
  type IssueCollectorOptions = {
3
6
  cwd: string;
4
7
  rules: Rules;
8
+ filters: Filters;
5
9
  };
6
10
  export declare class IssueCollector {
7
11
  private cwd;
8
12
  private rules;
13
+ private filters;
9
14
  private issues;
10
15
  private counters;
11
16
  private referencedFiles;
12
17
  private configurationHints;
13
- constructor({ cwd, rules }: IssueCollectorOptions);
18
+ constructor({ cwd, rules, filters }: IssueCollectorOptions);
14
19
  addFileCounts({ processed, unused }: {
15
20
  processed: number;
16
21
  unused: number;
@@ -7,13 +7,15 @@ function objectInSet(set, obj) {
7
7
  export class IssueCollector {
8
8
  cwd;
9
9
  rules;
10
+ filters;
10
11
  issues = initIssues();
11
12
  counters = initCounters();
12
13
  referencedFiles = new Set();
13
14
  configurationHints = new Set();
14
- constructor({ cwd, rules }) {
15
+ constructor({ cwd, rules, filters }) {
15
16
  this.cwd = cwd;
16
17
  this.rules = rules;
18
+ this.filters = filters;
17
19
  }
18
20
  addFileCounts({ processed, unused }) {
19
21
  this.counters.processed += processed;
@@ -21,14 +23,18 @@ export class IssueCollector {
21
23
  }
22
24
  addFilesIssues(filePaths) {
23
25
  filePaths.forEach(filePath => {
24
- if (!this.referencedFiles.has(filePath)) {
25
- this.issues.files.add(filePath);
26
- this.counters.files++;
27
- this.counters.processed++;
28
- }
26
+ if (this.filters.dir && !filePath.startsWith(this.filters.dir + '/'))
27
+ return;
28
+ if (this.referencedFiles.has(filePath))
29
+ return;
30
+ this.issues.files.add(filePath);
31
+ this.counters.files++;
32
+ this.counters.processed++;
29
33
  });
30
34
  }
31
35
  addIssue(issue) {
36
+ if (this.filters.dir && !issue.filePath.startsWith(this.filters.dir + '/'))
37
+ return;
32
38
  const key = relative(this.cwd, issue.filePath);
33
39
  issue.severity = this.rules[issue.type];
34
40
  this.issues[issue.type][key] = this.issues[issue.type][key] ?? {};
package/dist/index.js CHANGED
@@ -28,13 +28,15 @@ export const main = async (unresolvedConfiguration) => {
28
28
  const workspaces = chief.getWorkspaces();
29
29
  const report = chief.getIssueTypesToReport();
30
30
  const rules = chief.getRules();
31
+ const filters = chief.getFilters();
31
32
  const isReportDependencies = report.dependencies || report.unlisted || report.unresolved;
32
33
  const isReportValues = report.exports || report.nsExports || report.classMembers;
33
34
  const isReportTypes = report.types || report.nsTypes || report.enumMembers;
34
- const collector = new IssueCollector({ cwd, rules });
35
+ const collector = new IssueCollector({ cwd, rules, filters });
35
36
  const enabledPluginsStore = new Map();
36
37
  deputy.addIgnored(chief.config.ignoreBinaries, chief.config.ignoreDependencies);
37
- debugLogObject('Included workspaces', workspaces);
38
+ debugLogObject('Included workspaces', workspaces.map(w => w.pkgName));
39
+ debugLogObject('Included workspace configs', workspaces.map(w => ({ name: w.name, pkgName: w.pkgName, config: w.config, ancestors: w.ancestors })));
38
40
  const handleReferencedDependency = ({ specifier, containingFilePath, principal, workspace, }) => {
39
41
  if (isInternal(specifier)) {
40
42
  const absSpecifier = toAbsolute(specifier, dirname(containingFilePath));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knip",
3
- "version": "0.0.0-graph.0",
3
+ "version": "0.0.0-graph.2",
4
4
  "description": "Find unused files, dependencies and exports in your TypeScript and JavaScript projects",
5
5
  "homepage": "https://github.com/webpro/knip",
6
6
  "repository": "github:webpro/knip",
@@ -44,6 +44,7 @@
44
44
  "dependencies": {
45
45
  "@ericcornelissen/bash-parser": "^0.5.2",
46
46
  "@npmcli/map-workspaces": "^3.0.4",
47
+ "@pnpm/logger": "5.0.0",
47
48
  "@pnpm/workspace.pkgs-graph": "2.0.6",
48
49
  "@snyk/github-codeowners": "^1.1.0",
49
50
  "chalk": "^5.2.0",