Skip to content

Commit 84787b6

Browse files
committed
feat: support glob paths + support positional file arguments in CLI
1 parent 35c4eef commit 84787b6

File tree

6 files changed

+129
-45
lines changed

6 files changed

+129
-45
lines changed

Readme.md

+21-9
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,33 @@ dub build --config=executable --build=release-nobounds --compiler=ldc2
3232
### CLI Usage
3333

3434
```shell
35-
❯ minijson --help
35+
> minijson --help
36+
37+
Usage: minijson [--files FILES ...] [--comment] [--str STR ...] [--file FILE ...] [-h]
3638

3739
minijson: minify json files with support for comments
38-
minijson --file file1.json --file file2.json
39-
minijson --file file1_with_comment.json --file file2_with_comment.json --comment
4040

41-
minijson --string '{"some_json": "string_here"}'
42-
minijson --string '{"some_json": "string_here"} //comment' --comment
41+
# Minify the specified files
42+
minijson ./dist/**/*.json ./build/a.json
43+
44+
# Minify the specified files (supports comments)
45+
minijson --comment file1_with_comment.json file2_with_comment.json
46+
47+
# Minify the specified json string
48+
minijson --str '{"some_json": "string_here"}'
49+
50+
# Minify the specified json string (supports comments)
51+
minijson --comment --str '{"some_json": "string_here"} //comment'
4352

4453
More information at https://github.com/aminya/minijson
4554

46-
--file an array of files to minify
47-
--string a json string to minify
48-
--comment a flag to support comments in json
49-
-h --help This help information.
55+
56+
Optional arguments:
57+
--files FILES ...
58+
--comment
59+
--str STR ...
60+
--file FILE ...
61+
-h, --help Show this help message and exit
5062
```
5163

5264
### Node API

dub.sdl

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ sourcePaths "./src/native"
1010
importPaths "./src/native"
1111

1212
dependency "automem" version="0.6.7"
13-
preGenerateCommands "git submodule update --init" # despacer download
1413
dependency "despacer" path="despacer"
14+
dependency "d-glob" version="~>0.4.0"
15+
dependency "argparse" version="~>1.3.0"
16+
17+
preGenerateCommands "git submodule update --init" # despacer download
1518

1619
configuration "executable" {
1720
targetType "executable"
@@ -32,7 +35,7 @@ configuration "benchmark" {
3235

3336
# -------- Build Options and configurations --------
3437

35-
dflags "-vgc"
38+
// dflags "-vgc"
3639

3740
buildType "release-nobounds" {
3841
buildOptions "releaseMode" "optimize" "inline" "noBoundsCheck"

dub.selections.json

+3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
{
22
"fileVersion": 1,
33
"versions": {
4+
"argparse": "1.3.0",
45
"automem": "0.6.7",
6+
"bdd": "1.3.0",
7+
"d-glob": "0.4.0",
58
"despacer": {"path":"despacer/"},
69
"test_allocator": "0.3.4",
710
"unit-threaded": "2.2.0"

src/native/cli.d

+47-30
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,65 @@
11
module minijson.cli;
22

3-
import minijson.lib : minifyFiles, minifyString;
3+
import minijson.lib : minifyFiles, minifyStrings;
4+
import argparse;
45

5-
import std.getopt : getopt, defaultGetoptPrinter, GetoptResult;
6+
@(Command("minijson")
7+
.Description(`minijson: minify json files with support for comments
68
7-
/** Print help */
8-
void printHelp(GetoptResult optResult) @trusted
9-
{
10-
return defaultGetoptPrinter(`minijson: minify json files with support for comments
11-
minijson --file file1.json --file file2.json
12-
minijson --file file1_with_comment.json --file file2_with_comment.json --comment
9+
# Minify the specified files
10+
minijson ./dist/**/*.json ./build/a.json
11+
12+
# Minify the specified files (supports comments)
13+
minijson --comment file1_with_comment.json file2_with_comment.json
14+
15+
# Minify the specified json string
16+
minijson --str '{"some_json": "string_here"}'
1317
14-
minijson --string '{"some_json": "string_here"}'
15-
minijson --string '{"some_json": "string_here"} //comment' --comment
18+
# Minify the specified json string (supports comments)
19+
minijson --comment --str '{"some_json": "string_here"} //comment'
1620
1721
More information at https://github.com/aminya/minijson
18-
`, optResult.options);
22+
`)
23+
)
24+
struct Options
25+
{
26+
@TrailingArguments string[] files;
27+
bool comment = false;
28+
string[] str;
29+
// (Deprecated) A list of files to minify (for backwards compatiblitity with getopt)
30+
string[] file;
1931
}
2032

21-
void main(string[] args) @trusted
33+
int actualMain(Options opts) @trusted
2234
{
23-
string[] files;
24-
string jsonString;
25-
bool hasComment = false;
35+
try
36+
{
37+
// minify the given files
38+
if (opts.files.length > 0 || opts.file.length > 0)
39+
{
40+
const auto files = opts.files ~ opts.file;
41+
minifyFiles(files, opts.comment);
42+
}
2643

27-
auto optResult = getopt(args, "file", "an array of files to minify", &files, "string",
28-
"a json string to minify", &jsonString, "comment", "a flag to support comments in json", &hasComment);
44+
// minify the given string and print to stdout
45+
if (opts.str)
46+
{
47+
import std.algorithm : each;
48+
import std.stdio : writeln;
2949

30-
if (optResult.helpWanted || (!files && !jsonString))
31-
{
32-
return printHelp(optResult);
33-
}
50+
minifyStrings(opts.str, opts.comment).each!writeln;
3451

35-
// minify the given files
36-
if (files)
37-
{
38-
minifyFiles(files, hasComment);
52+
}
3953
}
40-
41-
// minify the given string and print to stdout
42-
if (jsonString)
54+
catch (Exception e)
4355
{
44-
import std : write;
56+
import std.stdio : stderr;
4557

46-
write(minifyString(jsonString, hasComment));
58+
stderr.writeln("Error: ", e.msg);
59+
return 1;
4760
}
61+
62+
return 0;
4863
}
64+
65+
mixin CLI!Options.main!((args) { return actualMain(args); });

src/native/lib.d

+52-3
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,66 @@ private bool hasNoSpace(const ref string str) @trusted
162162
}
163163
}
164164

165+
/**
166+
Minify the given JSON strings in parallel
167+
168+
Params:
169+
jsonStrings = the json strings you want to minify
170+
hasComment = a boolean to support comments in json. Default: `false`.
171+
172+
Return:
173+
the minified json strings
174+
*/
175+
string[] minifyStrings(in string[] jsonStrings, in bool hasComment = false) @trusted
176+
{
177+
import std.algorithm: map;
178+
import std.array: array;
179+
180+
return jsonStrings.map!(jsonString => minifyString(jsonString, hasComment)).array();
181+
}
182+
165183
/**
166184
Minify the given files in place. It minifies the files in parallel.
167185
168186
Params:
169-
files = the paths to the files.
187+
paths = the paths to the files. It could be glob patterns.
170188
hasComment = a boolean to support comments in json. Default: `false`.
171189
*/
172-
void minifyFiles(in string[] files, in bool hasComment = false)
190+
void minifyFiles(in string[] paths, in bool hasComment = false) @trusted
173191
{
174192
import std.parallelism : parallel;
175-
import std.file : readText, write;
193+
import std.algorithm;
194+
import std.array;
195+
import std.file : dirEntries, SpanMode, readText, write, isFile, isDir, exists;
196+
import std.path : globMatch;
197+
import glob : glob;
198+
import std.stdio : writeln;
199+
200+
// get the files from the given paths (resolve glob patterns)
201+
auto files = paths
202+
.map!((path) {
203+
if (path.exists)
204+
{
205+
if (path.isFile)
206+
{
207+
return [path];
208+
}
209+
else if (path.isDir)
210+
{
211+
return glob(path ~ "/**/*.json");
212+
}
213+
else
214+
{
215+
throw new Exception("The given path is not a file or a directory: " ~ path);
216+
}
217+
}
218+
else
219+
{
220+
return glob(path);
221+
}
222+
})
223+
.joiner()
224+
.array();
176225

177226
foreach (file; files.parallel())
178227
{

src/node/lib.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function minifyFiles(files: string[], hasComment = false): Promise<
5151
* @throws {Promise<string | Error>} The promise is rejected with the reason for failure
5252
*/
5353
export async function minifyString(jsonString: string, hasComment = false): Promise<string> {
54-
const args = ["--string", jsonString]
54+
const args = ["--str", jsonString]
5555
if (hasComment) {
5656
args.push("--comment")
5757
}

0 commit comments

Comments
 (0)