metascope 0.7.0 → 0.7.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.
- package/dist/bin/chunk-Bdh3yLIe.js +1 -0
- package/dist/bin/cli.js +308 -284
- package/dist/bin/dns-CUigd8AG.js +1 -0
- package/dist/bin/{jiti-D2Njwwqq.js → jiti-BTBDwj9g.js} +2 -2
- package/dist/bin/renovate-DxDKd5Ft.js +1 -0
- package/dist/bin/shared-CTlQdTfh.js +5 -0
- package/dist/lib/file-matching.js +20 -13
- package/dist/lib/log.d.ts +6 -4
- package/dist/lib/log.js +5 -3
- package/dist/lib/metadata-types.d.ts +33 -21
- package/dist/lib/metadata-types.js +8 -9
- package/dist/lib/metadata.js +7 -7
- package/dist/lib/package.js +1 -1
- package/dist/lib/parsers/gemspec-parser.js +16 -14
- package/dist/lib/parsers/go-mod-parser.js +13 -10
- package/dist/lib/parsers/makefile-config-parser.js +20 -17
- package/dist/lib/parsers/properties-parser.js +3 -3
- package/dist/lib/parsers/rfc822-header-parser.js +4 -4
- package/dist/lib/parsers/setup-py-parser.js +3 -4
- package/dist/lib/source.d.ts +1 -0
- package/dist/lib/source.js +5 -4
- package/dist/lib/sources/arduino-library-properties.d.ts +10 -10
- package/dist/lib/sources/arduino-library-properties.js +32 -15
- package/dist/lib/sources/cinder-cinderblock-xml.d.ts +11 -11
- package/dist/lib/sources/cinder-cinderblock-xml.js +21 -9
- package/dist/lib/sources/codemeta-json.d.ts +66 -66
- package/dist/lib/sources/codemeta-json.js +27 -23
- package/dist/lib/sources/git-stats.js +1 -1
- package/dist/lib/sources/github-actions.js +9 -2
- package/dist/lib/sources/github.js +1 -1
- package/dist/lib/sources/go-go-mod.d.ts +4 -4
- package/dist/lib/sources/go-goreleaser-yaml.d.ts +8 -8
- package/dist/lib/sources/go-goreleaser-yaml.js +5 -4
- package/dist/lib/sources/java-pom-xml.d.ts +12 -12
- package/dist/lib/sources/java-pom-xml.js +38 -19
- package/dist/lib/sources/metadata-file.d.ts +4 -4
- package/dist/lib/sources/metadata-file.js +15 -12
- package/dist/lib/sources/node-npm-registry.js +1 -1
- package/dist/lib/sources/openframeworks-addon-config-mk.d.ts +7 -7
- package/dist/lib/sources/openframeworks-addon-config-mk.js +7 -0
- package/dist/lib/sources/openframeworks-install-xml.d.ts +10 -10
- package/dist/lib/sources/openframeworks-install-xml.js +24 -14
- package/dist/lib/sources/processing-library-properties.d.ts +8 -8
- package/dist/lib/sources/processing-library-properties.js +25 -10
- package/dist/lib/sources/processing-sketch-properties.d.ts +16 -16
- package/dist/lib/sources/processing-sketch-properties.js +51 -7
- package/dist/lib/sources/publiccode-yaml.d.ts +23 -23
- package/dist/lib/sources/publiccode-yaml.js +37 -5
- package/dist/lib/sources/python-pkg-info.d.ts +18 -18
- package/dist/lib/sources/python-pkg-info.js +2 -2
- package/dist/lib/sources/python-setup-cfg.d.ts +14 -14
- package/dist/lib/sources/python-setup-cfg.js +2 -2
- package/dist/lib/sources/python-setup-py.d.ts +14 -14
- package/dist/lib/sources/readme-file.js +9 -2
- package/dist/lib/sources/ruby-gemspec.d.ts +22 -22
- package/dist/lib/sources/ruby-gemspec.js +1 -0
- package/dist/lib/sources/rust-cargo-toml.d.ts +14 -14
- package/dist/lib/sources/rust-cargo-toml.js +29 -10
- package/dist/lib/sources/xcode-info-plist.d.ts +12 -12
- package/dist/lib/sources/xcode-info-plist.js +48 -24
- package/dist/lib/sources/xcode-project-pbxproj.d.ts +8 -8
- package/dist/lib/sources/xcode-project-pbxproj.js +22 -12
- package/dist/lib/templates/codemeta-json.d.ts +4 -5
- package/dist/lib/templates/codemeta-json.js +4 -5
- package/dist/lib/templates/codemeta.js +30 -30
- package/dist/lib/templates/metadata.d.ts +2 -2
- package/dist/lib/templates/metadata.js +3 -3
- package/dist/lib/utilities/codemeta-helpers.d.ts +3 -2
- package/dist/lib/utilities/codemeta-helpers.js +14 -12
- package/dist/lib/utilities/fetch.js +2 -2
- package/dist/lib/utilities/formatting.js +4 -3
- package/dist/lib/utilities/github.js +3 -3
- package/dist/lib/utilities/license-identification.d.ts +3 -1
- package/dist/lib/utilities/license-identification.js +21 -25
- package/dist/lib/utilities/schema-primitives.js +16 -13
- package/dist/lib/utilities/template-helpers.js +3 -3
- package/package.json +14 -14
- package/readme.md +7 -3
- package/dist/.DS_Store +0 -0
- package/dist/bin/chunk-BjEoQXZ0.js +0 -1
|
@@ -11,8 +11,8 @@ import { escapePath, glob } from "tinyglobby";
|
|
|
11
11
|
const matchCache = /* @__PURE__ */ new Map();
|
|
12
12
|
const workspaceCache = /* @__PURE__ */ new Map();
|
|
13
13
|
/**
|
|
14
|
-
* Clear the memoized file tree and workspace caches. Call between test runs
|
|
15
|
-
*
|
|
14
|
+
* Clear the memoized file tree and workspace caches. Call between test runs or
|
|
15
|
+
* when the same path needs to be re-scanned.
|
|
16
16
|
*/
|
|
17
17
|
function resetMatchCache() {
|
|
18
18
|
matchCache.clear();
|
|
@@ -26,8 +26,9 @@ const DEFAULT_IGNORE = [
|
|
|
26
26
|
"**/.DS_Store"
|
|
27
27
|
];
|
|
28
28
|
/**
|
|
29
|
-
* Get the full recursive file tree for a directory, memoized by path +
|
|
30
|
-
* Returns relative POSIX paths (internal to tinyglobby; callers
|
|
29
|
+
* Get the full recursive file tree for a directory, memoized by path +
|
|
30
|
+
* respectIgnored. Returns relative POSIX paths (internal to tinyglobby; callers
|
|
31
|
+
* receive absolute paths via getMatches).
|
|
31
32
|
*/
|
|
32
33
|
async function getTree(path, respectIgnored) {
|
|
33
34
|
const key = `${path}\0${respectIgnored ? "1" : "0"}`;
|
|
@@ -93,13 +94,15 @@ function validateWorkspaces(directory, workspaces) {
|
|
|
93
94
|
return validated;
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
96
|
-
* Get workspace locations for a directory, memoized by directory path.
|
|
97
|
-
*
|
|
97
|
+
* Get workspace locations for a directory, memoized by directory path. Returns
|
|
98
|
+
* all found workspace location paths as absolute paths.
|
|
99
|
+
*
|
|
100
|
+
* Directories to any monorepo workspaces... only supports yarn, npm, pnpm,
|
|
101
|
+
* lerna, and bolt at the moment. Never includes the root path!
|
|
98
102
|
*
|
|
99
|
-
* Directories to any monorepo workspaces... only supports yarn, npm, pnpm, lerna, and bolt at the moment.
|
|
100
|
-
* Never includes the root path!
|
|
101
103
|
* @param directory - The root directory to search from
|
|
102
|
-
* @param workspaces - `false` to disable, `true` to auto-discover, `string[]`
|
|
104
|
+
* @param workspaces - `false` to disable, `true` to auto-discover, `string[]`
|
|
105
|
+
* for a manual list
|
|
103
106
|
*/
|
|
104
107
|
function getWorkspaces(directory, workspaces = true) {
|
|
105
108
|
if (workspaces === false) return [];
|
|
@@ -122,11 +125,15 @@ const DEFAULT_MATCH_OPTIONS = {
|
|
|
122
125
|
* - Memoizes the file tree internally (keyed by path + respectIgnored)
|
|
123
126
|
* - Auto-prepends `**\/` to patterns when `options.recursive` is true
|
|
124
127
|
* - Always uses case-insensitive matching
|
|
125
|
-
* - When `options.workspaces` is set, also matches files in workspace directories
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
+
* - When `options.workspaces` is set, also matches files in workspace directories
|
|
129
|
+
* dynamically.
|
|
130
|
+
*
|
|
131
|
+
* @param options - Must include `path`; optionally `recursive`,
|
|
132
|
+
* `respectIgnored`, and `workspaces`
|
|
133
|
+
* @param patterns - Root-relative glob patterns (e.g. `['package.json']`,
|
|
134
|
+
* `['*.gemspec']`)
|
|
128
135
|
* @param patternsRecursive - Optionally explicitly specify recursive pattern
|
|
129
|
-
*
|
|
136
|
+
* variation, otherwise `**\/` is prepended automatically
|
|
130
137
|
*/
|
|
131
138
|
async function getMatches(options, patterns, patternsRecursive) {
|
|
132
139
|
const resolved = defu(options, DEFAULT_MATCH_OPTIONS);
|
package/dist/lib/log.d.ts
CHANGED
|
@@ -2,10 +2,12 @@ import { ILogBasic, ILogLayer } from "lognow";
|
|
|
2
2
|
|
|
3
3
|
//#region src/lib/log.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Set the logger instance for the module.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Set the logger instance for the module. Export this for library consumers to
|
|
6
|
+
* inject their own logger.
|
|
7
|
+
*
|
|
8
|
+
* @param logger - Accepts either a LogLayer instance or a Console- or
|
|
9
|
+
* Stream-like log target
|
|
8
10
|
*/
|
|
9
|
-
declare function setLogger(logger?: ILogBasic | ILogLayer): void;
|
|
11
|
+
declare function setLogger(logger?: ILogBasic | ILogLayer<unknown>): void;
|
|
10
12
|
//#endregion
|
|
11
13
|
export { setLogger };
|
package/dist/lib/log.js
CHANGED
|
@@ -9,9 +9,11 @@ let log = createLogger({
|
|
|
9
9
|
name
|
|
10
10
|
});
|
|
11
11
|
/**
|
|
12
|
-
* Set the logger instance for the module.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Set the logger instance for the module. Export this for library consumers to
|
|
13
|
+
* inject their own logger.
|
|
14
|
+
*
|
|
15
|
+
* @param logger - Accepts either a LogLayer instance or a Console- or
|
|
16
|
+
* Stream-like log target
|
|
15
17
|
*/
|
|
16
18
|
function setLogger(logger) {
|
|
17
19
|
log = injectionHelper(logger);
|
|
@@ -36,8 +36,8 @@ import { XcodeProjectPbxprojData } from "./sources/xcode-project-pbxproj.js";
|
|
|
36
36
|
|
|
37
37
|
//#region src/lib/metadata-types.d.ts
|
|
38
38
|
/**
|
|
39
|
-
* The complete metadata context assembled from all sources.
|
|
40
|
-
*
|
|
39
|
+
* The complete metadata context assembled from all sources. Each key
|
|
40
|
+
* corresponds to a metadata source.
|
|
41
41
|
*/
|
|
42
42
|
type MetadataContext = {
|
|
43
43
|
arduinoLibraryProperties: ArduinoLibraryPropertiesData;
|
|
@@ -82,7 +82,8 @@ type MetadataContext = {
|
|
|
82
82
|
type SourceName = keyof MetadataContext;
|
|
83
83
|
/**
|
|
84
84
|
* User-supplied data passed to templates for parameterized ownership checks.
|
|
85
|
-
* All fields are optional; templates that don't need them can ignore the
|
|
85
|
+
* All fields are optional; templates that don't need them can ignore the
|
|
86
|
+
* argument.
|
|
86
87
|
*/
|
|
87
88
|
type TemplateData = {
|
|
88
89
|
[key: string]: unknown;
|
|
@@ -90,22 +91,21 @@ type TemplateData = {
|
|
|
90
91
|
githubAccount?: string | string[];
|
|
91
92
|
};
|
|
92
93
|
/**
|
|
93
|
-
* A template function that transforms MetadataContext into a custom shape.
|
|
94
|
-
*
|
|
94
|
+
* A template function that transforms MetadataContext into a custom shape. The
|
|
95
|
+
* optional second argument provides user-supplied template data.
|
|
95
96
|
*/
|
|
96
97
|
type Template<T> = (context: MetadataContext, templateData: TemplateData) => T;
|
|
97
98
|
/**
|
|
98
|
-
* Identity wrapper for type inference in config files.
|
|
99
|
-
*
|
|
99
|
+
* Identity wrapper for type inference in config files. Use this in
|
|
100
|
+
* `metascope.config.ts` to get autocomplete on available fields.
|
|
101
|
+
*
|
|
100
102
|
* @example
|
|
101
|
-
*
|
|
102
|
-
* import { defineTemplate } from 'metascope'
|
|
103
|
+
* import { defineTemplate } from 'metascope'
|
|
103
104
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* ```
|
|
105
|
+
* export default defineTemplate(({ codemetaJson, github }) => ({
|
|
106
|
+
* name: codemetaJson?.data.name,
|
|
107
|
+
* stars: github?.data.stargazerCount,
|
|
108
|
+
* }))
|
|
109
109
|
*/
|
|
110
110
|
declare function defineTemplate<T>(transform: Template<T>): Template<T>;
|
|
111
111
|
/**
|
|
@@ -118,18 +118,28 @@ type Credentials = {
|
|
|
118
118
|
* Base options shared by all `getMetadata` overloads.
|
|
119
119
|
*/
|
|
120
120
|
type GetMetadataBaseOptions = {
|
|
121
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* When true (the default), all paths in the output (source,
|
|
123
|
+
* workspaceDirectories, etc.) are absolute. When false, paths are relative to
|
|
124
|
+
* the project directory.
|
|
125
|
+
*/
|
|
126
|
+
absolute?: boolean; /** API credentials for remote sources. */
|
|
122
127
|
credentials?: Credentials; /** Skip web sources (npm registry, GitHub API, PyPI, etc.). */
|
|
123
|
-
offline?: boolean;
|
|
128
|
+
offline?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Project directory path. Defaults to `'.'` (resolved to `process.cwd()` via
|
|
131
|
+
* `path.resolve`).
|
|
132
|
+
*/
|
|
124
133
|
path: string; /** Search for metadata files recursively in subdirectories. Defaults to false. */
|
|
125
134
|
recursive?: boolean; /** Ignore files specified .gitignore in the file tree. Defaults to true. */
|
|
126
135
|
respectIgnored?: boolean; /** Only run these specific sources. Defaults to all sources when undefined. */
|
|
127
136
|
sources?: SourceName[]; /** User-supplied data passed to templates. */
|
|
128
137
|
templateData?: TemplateData;
|
|
129
138
|
/**
|
|
130
|
-
* Directories to any monorepo workspaces... only supports yarn, npm, pnpm,
|
|
131
|
-
* Never includes the root path!
|
|
132
|
-
*
|
|
139
|
+
* Directories to any monorepo workspaces... only supports yarn, npm, pnpm,
|
|
140
|
+
* lerna, and bolt at the moment Never includes the root path! False is
|
|
141
|
+
* disable, true is auto-discover which turns into string[], string[] is
|
|
142
|
+
* manual list relative to the project directory path...
|
|
133
143
|
*/
|
|
134
144
|
workspaces?: boolean | string[];
|
|
135
145
|
};
|
|
@@ -138,13 +148,15 @@ type GetMetadataBaseOptions = {
|
|
|
138
148
|
*/
|
|
139
149
|
declare const DEFAULT_GET_METADATA_OPTIONS: Required<Omit<GetMetadataBaseOptions, 'credentials' | 'sources' | 'templateData'>>;
|
|
140
150
|
/**
|
|
141
|
-
* Options for `getMetadata` without a template (returns full
|
|
151
|
+
* Options for `getMetadata` without a template (returns full
|
|
152
|
+
* `MetadataContext`).
|
|
142
153
|
*/
|
|
143
154
|
type GetMetadataOptions = GetMetadataBaseOptions & {
|
|
144
155
|
/** Built-in template name or omit for full output. */template?: 'frontmatter' | 'metadata' | 'project' | (string & {});
|
|
145
156
|
};
|
|
146
157
|
/**
|
|
147
|
-
* Options for `getMetadata` with a template function (returns the template's
|
|
158
|
+
* Options for `getMetadata` with a template function (returns the template's
|
|
159
|
+
* return type).
|
|
148
160
|
*/
|
|
149
161
|
type GetMetadataTemplateOptions<T> = GetMetadataBaseOptions & {
|
|
150
162
|
/** Template function that transforms MetadataContext into a custom shape. */template: Template<T>;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
//#region src/lib/metadata-types.ts
|
|
2
2
|
/**
|
|
3
|
-
* Identity wrapper for type inference in config files.
|
|
4
|
-
*
|
|
3
|
+
* Identity wrapper for type inference in config files. Use this in
|
|
4
|
+
* `metascope.config.ts` to get autocomplete on available fields.
|
|
5
|
+
*
|
|
5
6
|
* @example
|
|
6
|
-
*
|
|
7
|
-
* import { defineTemplate } from 'metascope'
|
|
7
|
+
* import { defineTemplate } from 'metascope'
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* ```
|
|
9
|
+
* export default defineTemplate(({ codemetaJson, github }) => ({
|
|
10
|
+
* name: codemetaJson?.data.name,
|
|
11
|
+
* stars: github?.data.stargazerCount,
|
|
12
|
+
* }))
|
|
14
13
|
*/
|
|
15
14
|
function defineTemplate(transform) {
|
|
16
15
|
return transform;
|
package/dist/lib/metadata.js
CHANGED
|
@@ -47,10 +47,10 @@ import prettyMs from "pretty-ms";
|
|
|
47
47
|
//#region src/lib/metadata.ts
|
|
48
48
|
const execFileAsync = promisify(execFile);
|
|
49
49
|
/**
|
|
50
|
-
* All registered metadata sources.
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
50
|
+
* All registered metadata sources. Each source declares its `phase` number.
|
|
51
|
+
* Sources with the same phase run in parallel. Lower phases run first, and
|
|
52
|
+
* their accumulated results are available to later phases via `context` in
|
|
53
|
+
* `SourceContext`.
|
|
54
54
|
*/
|
|
55
55
|
const sources = [
|
|
56
56
|
arduinoLibraryPropertiesSource,
|
|
@@ -112,11 +112,11 @@ async function resolveCredentials(credentials) {
|
|
|
112
112
|
return credentials ?? {};
|
|
113
113
|
}
|
|
114
114
|
/**
|
|
115
|
-
* Resolve a template option to a template function.
|
|
116
|
-
*
|
|
115
|
+
* Resolve a template option to a template function. Accepts a built-in template
|
|
116
|
+
* name (string) or a template function.
|
|
117
117
|
*/
|
|
118
118
|
function resolveTemplate(template) {
|
|
119
|
-
if (template === void 0) return
|
|
119
|
+
if (template === void 0) return;
|
|
120
120
|
if (typeof template === "function") return template;
|
|
121
121
|
if (isKeyOfTemplate(template)) return templates[template];
|
|
122
122
|
log.warn(`Unknown template: "${template}". Using default (all fields).`);
|
package/dist/lib/package.js
CHANGED
|
@@ -74,9 +74,11 @@ function extractStringArray(node) {
|
|
|
74
74
|
return single === void 0 ? [] : [single];
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
77
|
-
* Attempt to extract a usable value from an arbitrary RHS node.
|
|
78
|
-
*
|
|
79
|
-
* we can't statically
|
|
77
|
+
* Attempt to extract a usable value from an arbitrary RHS node. Returns string
|
|
78
|
+
*
|
|
79
|
+
* | string[] | null — we intentionally skip expressions we can't statically
|
|
80
|
+
*
|
|
81
|
+
* Evaluate (method calls, constants, etc.).
|
|
80
82
|
*/
|
|
81
83
|
function extractValue(node) {
|
|
82
84
|
if (node.type === "array" || node.type === "string_array") return extractStringArray(node);
|
|
@@ -89,7 +91,7 @@ function extractValue(node) {
|
|
|
89
91
|
}
|
|
90
92
|
if (node.type === "true") return "true";
|
|
91
93
|
if (node.type === "false") return "false";
|
|
92
|
-
if (node.type === "nil") return
|
|
94
|
+
if (node.type === "nil") return;
|
|
93
95
|
return extractString(node);
|
|
94
96
|
}
|
|
95
97
|
/** Resolve the attribute name from the LHS of `spec.foo = ...` */
|
|
@@ -102,9 +104,9 @@ const DEP_METHODS = {
|
|
|
102
104
|
add_runtime_dependency: "runtime"
|
|
103
105
|
};
|
|
104
106
|
function tryParseDependency(node) {
|
|
105
|
-
if (node.type !== "call" && node.type !== "method_call") return
|
|
107
|
+
if (node.type !== "call" && node.type !== "method_call") return;
|
|
106
108
|
const methodNode = node.childForFieldName("method");
|
|
107
|
-
if (!methodNode) return
|
|
109
|
+
if (!methodNode) return;
|
|
108
110
|
let methodName;
|
|
109
111
|
if (methodNode.type === "call") methodName = methodNode.childForFieldName("method")?.text ?? void 0;
|
|
110
112
|
else if (methodNode.type === "identifier") methodName = methodNode.text;
|
|
@@ -119,14 +121,14 @@ function tryParseDependency(node) {
|
|
|
119
121
|
break;
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
|
-
if (!methodName || !DEP_METHODS[methodName]) return
|
|
124
|
+
if (!methodName || !DEP_METHODS[methodName]) return;
|
|
123
125
|
const depType = DEP_METHODS[methodName];
|
|
124
126
|
const arguments_ = node.childForFieldName("arguments");
|
|
125
|
-
if (!arguments_) return
|
|
127
|
+
if (!arguments_) return;
|
|
126
128
|
const argumentNodes = children(arguments_);
|
|
127
|
-
if (argumentNodes.length === 0) return
|
|
129
|
+
if (argumentNodes.length === 0) return;
|
|
128
130
|
const depName = extractString(argumentNodes[0]);
|
|
129
|
-
if (!depName) return
|
|
131
|
+
if (!depName) return;
|
|
130
132
|
return {
|
|
131
133
|
name: depName,
|
|
132
134
|
requirements: argumentNodes.slice(1).map((element) => extractString(element)).filter((s) => s !== void 0),
|
|
@@ -157,12 +159,12 @@ function setArrayAttribute(spec, key, value) {
|
|
|
157
159
|
* Parse a `.gemspec` file's contents and return a plain object with the
|
|
158
160
|
* extracted fields.
|
|
159
161
|
*
|
|
160
|
-
* Uses tree-sitter with the Ruby grammar to walk the AST, so it can handle
|
|
161
|
-
*
|
|
162
|
+
* Uses tree-sitter with the Ruby grammar to walk the AST, so it can handle most
|
|
163
|
+
* real-world gemspec patterns without executing Ruby.
|
|
162
164
|
*
|
|
163
165
|
* Fields that reference Ruby constants (e.g. `Foo::VERSION`) or dynamic
|
|
164
|
-
* expressions (e.g. `Dir.glob(...)`) will be `null` / empty — the parser
|
|
165
|
-
*
|
|
166
|
+
* expressions (e.g. `Dir.glob(...)`) will be `null` / empty — the parser only
|
|
167
|
+
* extracts statically determinable values.
|
|
166
168
|
*/
|
|
167
169
|
async function parseGemspec(source) {
|
|
168
170
|
const parser = await initParser();
|
|
@@ -20,9 +20,9 @@ const HOST_SEGMENTS = {
|
|
|
20
20
|
function moduleToRepoUrl(modulePath) {
|
|
21
21
|
const segments = modulePath.split("/");
|
|
22
22
|
const host = segments[0];
|
|
23
|
-
if (!host) return
|
|
23
|
+
if (!host) return;
|
|
24
24
|
const needed = HOST_SEGMENTS[host];
|
|
25
|
-
if (!needed || segments.length < needed) return
|
|
25
|
+
if (!needed || segments.length < needed) return;
|
|
26
26
|
let repoPath = segments.slice(0, needed).join("/");
|
|
27
27
|
repoPath = repoPath.replace(MAJOR_VERSION_SUFFIX_REGEX, "");
|
|
28
28
|
return `https://${repoPath}`;
|
|
@@ -41,7 +41,7 @@ function parseRequireLine(line) {
|
|
|
41
41
|
const indirect = isIndirect(line);
|
|
42
42
|
const clean = stripComment(line);
|
|
43
43
|
const match = MODULE_VERSION_REGEX.exec(clean);
|
|
44
|
-
if (!match) return
|
|
44
|
+
if (!match) return;
|
|
45
45
|
const version = match[2].replace(INCOMPATIBLE_SUFFIX_REGEX, "");
|
|
46
46
|
return {
|
|
47
47
|
indirect,
|
|
@@ -49,16 +49,19 @@ function parseRequireLine(line) {
|
|
|
49
49
|
version
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Parse a replace-style line: `old [version] => new version` or `old [version]
|
|
54
|
+
* => ./local`
|
|
55
|
+
*/
|
|
53
56
|
function parseReplaceLine(line) {
|
|
54
57
|
const parts = stripComment(line).split("=>");
|
|
55
|
-
if (parts.length !== 2) return
|
|
58
|
+
if (parts.length !== 2) return;
|
|
56
59
|
const left = parts[0].trim().split(WHITESPACE_REGEX);
|
|
57
60
|
const right = parts[1].trim().split(WHITESPACE_REGEX);
|
|
58
61
|
const from = left[0];
|
|
59
|
-
if (!from || right.length === 0) return
|
|
62
|
+
if (!from || right.length === 0) return;
|
|
60
63
|
const target = right[0];
|
|
61
|
-
if (!target) return
|
|
64
|
+
if (!target) return;
|
|
62
65
|
if (target.startsWith("./") || target.startsWith("../") || target.startsWith("/")) return {
|
|
63
66
|
from,
|
|
64
67
|
to: "local"
|
|
@@ -74,14 +77,14 @@ function parseReplaceLine(line) {
|
|
|
74
77
|
/** Parse a tool-style line: just a module path. */
|
|
75
78
|
function parseToolLine(line) {
|
|
76
79
|
const clean = stripComment(line).trim();
|
|
77
|
-
if (clean.length === 0) return
|
|
80
|
+
if (clean.length === 0) return;
|
|
78
81
|
return clean.split(WHITESPACE_REGEX)[0] || void 0;
|
|
79
82
|
}
|
|
80
83
|
/**
|
|
81
84
|
* Parse a go.mod file and return structured metadata.
|
|
82
85
|
*
|
|
83
|
-
* Extracts module identity, Go version, direct dependencies (skipping
|
|
84
|
-
*
|
|
86
|
+
* Extracts module identity, Go version, direct dependencies (skipping indirect
|
|
87
|
+
* ones), tool dependencies, and applies replace directives.
|
|
85
88
|
*/
|
|
86
89
|
function parseGoMod(source) {
|
|
87
90
|
const data = {
|
|
@@ -2,23 +2,26 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Parser for Makefile-style configuration files.
|
|
4
4
|
*
|
|
5
|
-
* These files use a GNU Makefile-like syntax with section headers (lines
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* These files use a GNU Makefile-like syntax with section headers (lines ending
|
|
6
|
+
* in `:`) and variable assignments (`VAR = value` or `VAR += value`). This
|
|
7
|
+
* parser extracts metadata from the `meta:` section and structural information
|
|
8
|
+
* (dependencies, platform sections) from the rest of the file.
|
|
9
9
|
*
|
|
10
|
-
* The parser is intentionally simple — no Make variable expansion, no
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* The parser is intentionally simple — no Make variable expansion, no includes,
|
|
11
|
+
* no conditionals. It mirrors the line-by-line algorithm used by the
|
|
12
|
+
* openFrameworks Project Generator.
|
|
13
13
|
*/
|
|
14
14
|
const INLINE_COMMENT_REGEX = /#.*$/;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Section header pattern: a word (with optional hyphens/slashes) followed by a
|
|
17
|
+
* colon.
|
|
18
|
+
*/
|
|
16
19
|
const SECTION_RE = /^[\w/][\w/-]*:$/;
|
|
17
|
-
/** Variable assignment pattern: VARNAME = value
|
|
20
|
+
/** Variable assignment pattern: VARNAME = value or VARNAME += value */
|
|
18
21
|
const ASSIGNMENT_RE = /^(\w+)\s*(\+?=)\s*(.*)/;
|
|
19
22
|
/**
|
|
20
|
-
* Sections that are not platform-specific and should be excluded
|
|
21
|
-
*
|
|
23
|
+
* Sections that are not platform-specific and should be excluded from
|
|
24
|
+
* operatingSystem inference.
|
|
22
25
|
*/
|
|
23
26
|
const NON_PLATFORM_SECTIONS = new Set([
|
|
24
27
|
"all",
|
|
@@ -74,20 +77,20 @@ function parseMakefileConfig(content) {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
/**
|
|
77
|
-
* Get a single string value from the meta variables map.
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
+
* Get a single string value from the meta variables map. Joins multiple tokens
|
|
81
|
+
* with spaces (for values split across `+=` lines). Returns undefined for
|
|
82
|
+
* empty/whitespace-only results.
|
|
80
83
|
*/
|
|
81
84
|
function singleValue(variables, key) {
|
|
82
85
|
const values = variables.get(key);
|
|
83
|
-
if (!values || values.length === 0) return
|
|
86
|
+
if (!values || values.length === 0) return;
|
|
84
87
|
const joined = values.join(" ").trim();
|
|
85
88
|
return joined.length > 0 ? joined : void 0;
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
88
91
|
* Tokenize a value string, handling both bare tokens and "quoted multi-word"
|
|
89
|
-
* tokens. For example:
|
|
90
|
-
*
|
|
92
|
+
* tokens. For example: `"computer vision" "opencv" bare` → `["computer vision",
|
|
93
|
+
* "opencv", "bare"]`
|
|
91
94
|
*/
|
|
92
95
|
function tokenizeValues(raw) {
|
|
93
96
|
const trimmed = raw.trim();
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Parser for Java `*.properties` files (key=value format).
|
|
4
4
|
*
|
|
5
|
-
* Used by both Arduino and Processing IDE library managers. These are
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Used by both Arduino and Processing IDE library managers. These are flat
|
|
6
|
+
* UTF-8 properties files with no sections or nesting. Comment lines start with
|
|
7
|
+
* `#`. Only the first `=` on each line is the delimiter.
|
|
8
8
|
*
|
|
9
9
|
* Returns raw key-value pairs — all domain-specific validation and
|
|
10
10
|
* transformation is handled by the consuming source.
|
|
@@ -10,9 +10,9 @@ const MULTI_VALUE_HEADERS = new Set([
|
|
|
10
10
|
"Supported-Platform"
|
|
11
11
|
]);
|
|
12
12
|
/**
|
|
13
|
-
* Parse RFC 822-style headers from PKG-INFO / METADATA content.
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* Parse RFC 822-style headers from PKG-INFO / METADATA content. Multi-value
|
|
14
|
+
* headers are collected into newline-separated strings. Stops at the first
|
|
15
|
+
* blank line (which separates headers from body).
|
|
16
16
|
*/
|
|
17
17
|
function parseRfc822Headers(content) {
|
|
18
18
|
const headers = {};
|
|
@@ -37,7 +37,7 @@ function parseRfc822Headers(content) {
|
|
|
37
37
|
/** Extract body text after the first blank line. */
|
|
38
38
|
function extractRfc822Body(content) {
|
|
39
39
|
const blankIndex = content.indexOf("\n\n");
|
|
40
|
-
if (blankIndex === -1) return
|
|
40
|
+
if (blankIndex === -1) return;
|
|
41
41
|
return content.slice(blankIndex + 2).trim() || void 0;
|
|
42
42
|
}
|
|
43
43
|
/** Split newline-separated multi-value into array. */
|
|
@@ -101,10 +101,9 @@ const STRING_ATTRS = new Set([
|
|
|
101
101
|
/**
|
|
102
102
|
* Parse a setup.py file and return structured metadata.
|
|
103
103
|
*
|
|
104
|
-
* Uses tree-sitter with the Python grammar to find the `setup()` call
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* are skipped.
|
|
104
|
+
* Uses tree-sitter with the Python grammar to find the `setup()` call and
|
|
105
|
+
* extract keyword arguments. Only statically determinable values (string/list
|
|
106
|
+
* literals) are extracted — variables and dynamic expressions are skipped.
|
|
108
107
|
*/
|
|
109
108
|
async function parseSetupPy(source) {
|
|
110
109
|
const parser = await initParser();
|
package/dist/lib/source.d.ts
CHANGED
package/dist/lib/source.js
CHANGED
|
@@ -2,8 +2,9 @@ import { log } from "./log.js";
|
|
|
2
2
|
import { formatPath } from "./utilities/formatting.js";
|
|
3
3
|
//#region src/lib/source.ts
|
|
4
4
|
/**
|
|
5
|
-
* Define a metadata source with `discover` + `parse`.
|
|
6
|
-
*
|
|
5
|
+
* Define a metadata source with `discover` + `parse`. Automatically wires them
|
|
6
|
+
* into an `extract` implementation that handles:
|
|
7
|
+
*
|
|
7
8
|
* - Empty input check (returns undefined)
|
|
8
9
|
* - Per-input try/catch with log.warn
|
|
9
10
|
* - Filtering undefined results from parse
|
|
@@ -14,7 +15,7 @@ function defineSource(config) {
|
|
|
14
15
|
...config,
|
|
15
16
|
async extract(context) {
|
|
16
17
|
const inputs = await config.discover(context);
|
|
17
|
-
if (inputs.length === 0) return
|
|
18
|
+
if (inputs.length === 0) return;
|
|
18
19
|
const results = [];
|
|
19
20
|
for (const input of inputs) try {
|
|
20
21
|
const result = await config.parse(input, context);
|
|
@@ -25,7 +26,7 @@ function defineSource(config) {
|
|
|
25
26
|
} catch (error) {
|
|
26
27
|
log.warn(`Failed to process "${input}": ${error instanceof Error ? error.message : String(error)}`);
|
|
27
28
|
}
|
|
28
|
-
if (results.length === 0) return
|
|
29
|
+
if (results.length === 0) return;
|
|
29
30
|
return results.length === 1 ? results[0] : results;
|
|
30
31
|
}
|
|
31
32
|
};
|
|
@@ -3,7 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
|
|
4
4
|
//#region src/lib/sources/arduino-library-properties.d.ts
|
|
5
5
|
declare const arduinoLibraryPropertiesSchema: z.ZodObject<{
|
|
6
|
-
architectures: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString
|
|
6
|
+
architectures: z.ZodDefault<z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>>;
|
|
7
7
|
authors: z.ZodArray<z.ZodObject<{
|
|
8
8
|
email: z.ZodOptional<z.ZodString>;
|
|
9
9
|
name: z.ZodString;
|
|
@@ -24,20 +24,20 @@ declare const arduinoLibraryPropertiesSchema: z.ZodObject<{
|
|
|
24
24
|
name: z.ZodString;
|
|
25
25
|
versionConstraint: z.ZodOptional<z.ZodString>;
|
|
26
26
|
}, z.core.$strip>>;
|
|
27
|
-
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
28
|
-
includes: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString
|
|
29
|
-
license: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
27
|
+
email: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
28
|
+
includes: z.ZodDefault<z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>>;
|
|
29
|
+
license: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
30
30
|
maintainer: z.ZodOptional<z.ZodObject<{
|
|
31
31
|
email: z.ZodOptional<z.ZodString>;
|
|
32
32
|
name: z.ZodString;
|
|
33
33
|
}, z.core.$strip>>;
|
|
34
|
-
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
35
|
-
paragraph: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
34
|
+
name: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
35
|
+
paragraph: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
36
36
|
raw: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
37
|
-
repository: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
38
|
-
sentence: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
39
|
-
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
40
|
-
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
37
|
+
repository: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
38
|
+
sentence: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
39
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
40
|
+
version: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
41
41
|
}, z.core.$strip>;
|
|
42
42
|
type ArduinoLibraryProperties = z.infer<typeof arduinoLibraryPropertiesSchema>;
|
|
43
43
|
type ArduinoLibraryPropertiesData = OneOrMany<SourceRecord<ArduinoLibraryProperties>> | undefined;
|