Skip to content

Commit 571dce8

Browse files
committed
Merge branch 'develop' of https://github.com/stdlib-js/stdlib into develop
2 parents 59de9af + a908d77 commit 571dce8

File tree

26 files changed

+1800
-9
lines changed

26 files changed

+1800
-9
lines changed

.github/workflows/scripts/lint_package_json_files

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,32 @@ root=$(git rev-parse --show-toplevel)
3232
# Define the path to a utility for linting package.json files:
3333
lint_package_json="${root}/lib/node_modules/@stdlib/_tools/lint/pkg-json/bin/cli"
3434

35+
# Define the path to the package name validation tool:
36+
validate_package_names="${root}/lib/node_modules/@stdlib/_tools/lint/pkg-json-names/bin/cli"
37+
3538
# Define paths to utilities for updating package.json metadata fields:
3639
update_package_json_directories="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_directories"
3740
update_package_json_gypfile="${root}/lib/node_modules/@stdlib/_tools/package-json/scripts/update_gypfile"
3841

3942
# Files to process:
4043
files_to_process="$*"
4144

45+
# Initialize needs_changes flag:
46+
needs_changes=0
47+
4248
# Lint package.json files:
4349
files=$(echo "${files_to_process}" | tr ' ' '\n' | grep 'package\.json$' | grep -v 'datapackage\.json$' | tr '\n' ' ' | sed 's/ $//')
4450
if [ -n "${files}" ]; then
4551
echo "Linting package.json files..."
4652
printf '%s' "${files}" | "${lint_package_json}" --split=" "
53+
54+
echo "Validating package names..."
55+
for file in ${files}; do
56+
if ! node "${validate_package_names}" --pattern "${file}"; then
57+
echo "ERROR: Package name validation failed"
58+
needs_changes=1
59+
fi
60+
done
4761
else
4862
echo "No package.json files to lint."
4963
fi
@@ -55,8 +69,6 @@ dirs=$(echo "${files_to_process}" | tr ' ' '\n' | \
5569
sort -u)
5670

5771
echo "Checking package.json files in directories: ${dirs}"
58-
59-
needs_changes=0
6072
for dir in ${dirs}; do
6173
echo "Checking package.json in ${dir}..."
6274
package_json="${dir}/package.json"
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
<!--
2+
3+
@license Apache-2.0
4+
5+
Copyright (c) 2025 The Stdlib Authors.
6+
7+
Licensed under the Apache License, Version 2.0 (the "License");
8+
you may not use this file except in compliance with the License.
9+
You may obtain a copy of the License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
-->
20+
21+
# Lint
22+
23+
> Lint @stdlib package.json names to ensure they match their directory location.
24+
25+
<section class="usage">
26+
27+
## Usage
28+
29+
```javascript
30+
var lint = require( '@stdlib/_tools/lint/pkg-json-names' );
31+
```
32+
33+
#### lint( \[options,] clbk )
34+
35+
Asynchronously lints @stdlib package.json names to ensure that each package name matches its directory location within the stdlib project structure.
36+
37+
```javascript
38+
lint( onLint );
39+
40+
function onLint( error, errs ) {
41+
if ( error ) {
42+
throw error;
43+
}
44+
if ( errs.length ) {
45+
console.error( JSON.stringify( errs ) );
46+
} else {
47+
console.log( 'No detected errors.' );
48+
}
49+
}
50+
```
51+
52+
The function accepts the following `options`:
53+
54+
- **dir**: root directory from which to search for @stdlib package.json files to lint. May be either an absolute file path or a path relative to the `stdlib/lib/node_modules/` directory. Default: `/path/to/stdlib/lib/node_modules/`.
55+
- **pattern**: glob pattern for finding @stdlib package.json files. Default: `**/@stdlib/**/package.json`.
56+
- **ignore**: glob pattern(s) to exclude.
57+
58+
Each lint error is represented by an `object` having the following fields:
59+
60+
- **file**: @stdlib package.json file path.
61+
- **expected**: expected @stdlib package name based on directory location.
62+
- **actual**: actual package name found in package.json.
63+
- **message**: error message describing the mismatch.
64+
65+
To lint starting from a descendant directory, set the `dir` option.
66+
67+
```javascript
68+
var opts = {
69+
'dir': './@stdlib/math/base'
70+
};
71+
72+
lint( opts, onLint );
73+
74+
function onLint( error, errs ) {
75+
if ( error ) {
76+
throw error;
77+
}
78+
if ( errs.length ) {
79+
console.error( JSON.stringify( errs ) );
80+
} else {
81+
console.log( 'No detected errors.' );
82+
}
83+
}
84+
```
85+
86+
#### lint.sync( \[options] )
87+
88+
Synchronously lints @stdlib package.json names to ensure that each package name matches its directory location within the stdlib project structure.
89+
90+
```javascript
91+
var errs = lint.sync();
92+
if ( errs.length ) {
93+
console.error( JSON.stringify( errs ) );
94+
} else {
95+
console.log( 'No detected errors.' );
96+
}
97+
```
98+
99+
The function accepts the same `options` as `lint()` above.
100+
101+
</section>
102+
103+
<!-- /.usage -->
104+
105+
<section class="notes">
106+
107+
## Notes
108+
109+
- The function only lints packages under the `@stdlib` scope.
110+
- @stdlib package names must start with `@stdlib/` and match their directory location exactly.
111+
- For example, a package located at `lib/node_modules/@stdlib/math/base/special/abs/` must be named `@stdlib/math/base/special/abs`.
112+
- The tool validates that the package name corresponds to the actual directory structure within the stdlib project.
113+
114+
</section>
115+
116+
<!-- /.notes -->
117+
118+
<section class="examples">
119+
120+
## Examples
121+
122+
<!-- eslint no-undef: "error" -->
123+
124+
```javascript
125+
var lint = require( '@stdlib/_tools/lint/pkg-json-names' );
126+
127+
var opts = {
128+
'dir': './'
129+
};
130+
131+
lint( opts, onLint );
132+
133+
function onLint( error, errors ) {
134+
if ( error ) {
135+
throw error;
136+
}
137+
if ( errors.length ) {
138+
console.error( JSON.stringify( errors ) );
139+
} else {
140+
console.log( 'No detected errors.' );
141+
}
142+
}
143+
```
144+
145+
</section>
146+
147+
<!-- /.examples -->
148+
149+
* * *
150+
151+
<section class="cli">
152+
153+
## CLI
154+
155+
<section class="usage">
156+
157+
### Usage
158+
159+
```text
160+
Usage: stdlib-lint-pkg-json-names [options] [<dir>]
161+
162+
Options:
163+
164+
-h, --help Print this message.
165+
-V, --version Print the package version.
166+
--pattern pattern Pattern to match files for linting.
167+
--ignore pattern Exclusion glob pattern.
168+
```
169+
170+
</section>
171+
172+
<!-- /.usage -->
173+
174+
<section class="notes">
175+
176+
### Notes
177+
178+
- If not provided a `dir` argument, the search directory is the current working directory.
179+
180+
</section>
181+
182+
<!-- /.notes -->
183+
184+
<section class="examples">
185+
186+
### Examples
187+
188+
```bash
189+
$ stdlib-lint-pkg-json-names
190+
```
191+
192+
</section>
193+
194+
<!-- /.examples -->
195+
196+
</section>
197+
198+
<!-- /.cli -->
199+
200+
<!-- Section for related `stdlib` packages. Do not manually edit this section, as it is automatically populated. -->
201+
202+
<section class="related">
203+
204+
</section>
205+
206+
<!-- /.related -->
207+
208+
<!-- Section for all links. Make sure to keep an empty line after the `section` element and another before the `/section` close. -->
209+
210+
<section class="links">
211+
212+
</section>
213+
214+
<!-- /.links -->
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* @license Apache-2.0
5+
*
6+
* Copyright (c) 2025 The Stdlib Authors.
7+
*
8+
* Licensed under the Apache License, Version 2.0 (the "License");
9+
* you may not use this file except in compliance with the License.
10+
* You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
'use strict';
22+
23+
// MODULES //
24+
25+
var join = require( 'path' ).join;
26+
var readFileSync = require( '@stdlib/fs/read-file' ).sync;
27+
var CLI = require( '@stdlib/cli/ctor' );
28+
var lint = require( './../lib' );
29+
30+
31+
// MAIN //
32+
33+
/**
34+
* Main execution sequence.
35+
*
36+
* @private
37+
*/
38+
function main() {
39+
var flags;
40+
var args;
41+
var opts;
42+
var cli;
43+
44+
// Create a command-line interface:
45+
cli = new CLI({
46+
'pkg': require( './../package.json' ),
47+
'options': require( './../etc/cli_opts.json' ),
48+
'help': readFileSync( join( __dirname, '..', 'docs', 'usage.txt' ), {
49+
'encoding': 'utf8'
50+
})
51+
});
52+
53+
// Get any provided command-line arguments:
54+
flags = cli.flags();
55+
args = cli.args();
56+
57+
// Exit early if help or version was requested (CLI handles these automatically):
58+
if ( flags.help || flags.version ) {
59+
return;
60+
}
61+
62+
opts = {};
63+
if ( flags.pattern ) {
64+
opts.pattern = flags.pattern;
65+
}
66+
if ( flags.ignore ) {
67+
opts.ignore = flags.ignore;
68+
}
69+
if ( args.length ) {
70+
opts.dir = args[ 0 ];
71+
}
72+
73+
// Lint package.json names:
74+
lint( opts, onLint );
75+
76+
/**
77+
* Callback invoked upon completion.
78+
*
79+
* @private
80+
* @param {(Error|null)} error - error object
81+
* @param {ObjectArray} errs - lint errors
82+
* @returns {void}
83+
*/
84+
function onLint( error, errs ) {
85+
var i;
86+
if ( error ) {
87+
console.error( error.message ); // eslint-disable-line no-console
88+
return cli.exit( 1 );
89+
}
90+
if ( errs.length === 0 ) {
91+
return cli.exit( 0 );
92+
}
93+
for ( i = 0; i < errs.length; i++ ) {
94+
console.error( JSON.stringify( errs[ i ] ) ); // eslint-disable-line no-console
95+
}
96+
cli.exit( 1 );
97+
}
98+
}
99+
100+
main();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Usage: stdlib-lint-pkg-json-names [options] [<dir>]
2+
3+
Options:
4+
5+
-h, --help Print this message.
6+
-V, --version Print the package version.
7+
--pattern pattern Pattern to match files for linting.
8+
--ignore pattern Exclusion glob pattern.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"string": [
3+
"pattern",
4+
"ignore"
5+
],
6+
"boolean": [
7+
"help",
8+
"version"
9+
],
10+
"alias": {
11+
"help": [
12+
"h"
13+
],
14+
"version": [
15+
"V"
16+
]
17+
}
18+
}

0 commit comments

Comments
 (0)