@produtype/core 0.51.0 → 0.52.0

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.
@@ -15,18 +15,40 @@ const OTHER_MANIFESTS = [
15
15
  { manager: 'pub', pattern: /(^|\/)pubspec\.yaml$/ },
16
16
  { manager: 'composer', pattern: /(^|\/)composer\.json$/ },
17
17
  { manager: 'go modules', pattern: /(^|\/)go\.mod$/ },
18
+ { manager: 'cargo', pattern: /(^|\/)Cargo\.toml$/ },
18
19
  { manager: 'bundler', pattern: /(^|\/)Gemfile$/ },
19
20
  { manager: 'gradle', pattern: /(^|\/)build\.gradle(\.kts)?$/ },
20
21
  { manager: 'maven', pattern: /(^|\/)pom\.xml$/ },
21
22
  { manager: 'nuget', pattern: /\.(csproj|fsproj|vbproj)$/i },
22
23
  ];
24
+ /**
25
+ * The shallowest manifest wins, and list order only breaks a tie.
26
+ *
27
+ * The list was scanned in order, so the first pattern with any match anywhere decided.
28
+ * A Rust service with a small Go client SDK beside it reported its package manager as
29
+ * "go modules" while the line above it said the backend was axum — two lines of the
30
+ * same report disagreeing about what the project is.
31
+ *
32
+ * Depth is the signal that was already there. A manifest at the root, or nearer it, is
33
+ * the project's; one buried under `sdk/go/` belongs to something the project ships
34
+ * rather than something it is built with.
35
+ */
23
36
  function resolveFromOtherManifests(files) {
24
- for (const { manager, pattern } of OTHER_MANIFESTS) {
25
- const match = files.find((file) => pattern.test(file));
26
- if (match)
27
- return { manager, confidence: 'manifest', warnings: [], evidence: [match] };
28
- }
29
- return null;
37
+ let best = null;
38
+ OTHER_MANIFESTS.forEach(({ manager, pattern }, order) => {
39
+ for (const file of files) {
40
+ if (!pattern.test(file))
41
+ continue;
42
+ const depth = file.split('/').length;
43
+ if (!best || depth < best.depth || (depth === best.depth && order < best.order)) {
44
+ best = { manager, file, depth, order };
45
+ }
46
+ }
47
+ });
48
+ if (!best)
49
+ return null;
50
+ const { manager, file } = best;
51
+ return { manager, confidence: 'manifest', warnings: [], evidence: [file] };
30
52
  }
31
53
  function resolveWorkspaceManager(workspace) {
32
54
  const warnings = [];
@@ -10,7 +10,7 @@
10
10
  * Only managers whose manifest this analyzer actually reads are named here. A name it
11
11
  * cannot back with a parsed file would be a guess from a filename.
12
12
  */
13
- export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'pip' | 'poetry' | 'python' | 'pub' | 'composer' | 'go modules' | 'bundler' | 'gradle' | 'maven' | 'nuget' | 'unknown';
13
+ export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'pip' | 'poetry' | 'python' | 'pub' | 'composer' | 'go modules' | 'cargo' | 'bundler' | 'gradle' | 'maven' | 'nuget' | 'unknown';
14
14
  export type PackageManagerConfidence = 'lockfile' | 'manifest' | 'inferred' | 'unknown';
15
15
  export interface WorkspaceStack {
16
16
  root: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {