Skip to content

Commit

Permalink
feat: support glob paths + support positional file arguments in CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya committed Sep 6, 2024
1 parent 35c4eef commit 84787b6
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 45 deletions.
30 changes: 21 additions & 9 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,33 @@ dub build --config=executable --build=release-nobounds --compiler=ldc2
### CLI Usage

```shell
❯ minijson --help
> minijson --help

Usage: minijson [--files FILES ...] [--comment] [--str STR ...] [--file FILE ...] [-h]

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

minijson --string '{"some_json": "string_here"}'
minijson --string '{"some_json": "string_here"} //comment' --comment
# Minify the specified files
minijson ./dist/**/*.json ./build/a.json

# Minify the specified files (supports comments)
minijson --comment file1_with_comment.json file2_with_comment.json

# Minify the specified json string
minijson --str '{"some_json": "string_here"}'

# Minify the specified json string (supports comments)
minijson --comment --str '{"some_json": "string_here"} //comment'

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

--file an array of files to minify
--string a json string to minify
--comment a flag to support comments in json
-h --help This help information.

Optional arguments:
--files FILES ...
--comment
--str STR ...
--file FILE ...
-h, --help Show this help message and exit
```

### Node API
Expand Down
7 changes: 5 additions & 2 deletions dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ sourcePaths "./src/native"
importPaths "./src/native"

dependency "automem" version="0.6.7"
preGenerateCommands "git submodule update --init" # despacer download
dependency "despacer" path="despacer"
dependency "d-glob" version="~>0.4.0"
dependency "argparse" version="~>1.3.0"

preGenerateCommands "git submodule update --init" # despacer download

configuration "executable" {
targetType "executable"
Expand All @@ -32,7 +35,7 @@ configuration "benchmark" {

# -------- Build Options and configurations --------

dflags "-vgc"
// dflags "-vgc"

buildType "release-nobounds" {
buildOptions "releaseMode" "optimize" "inline" "noBoundsCheck"
Expand Down
3 changes: 3 additions & 0 deletions dub.selections.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"fileVersion": 1,
"versions": {
"argparse": "1.3.0",
"automem": "0.6.7",
"bdd": "1.3.0",
"d-glob": "0.4.0",
"despacer": {"path":"despacer/"},
"test_allocator": "0.3.4",
"unit-threaded": "2.2.0"
Expand Down
77 changes: 47 additions & 30 deletions src/native/cli.d
Original file line number Diff line number Diff line change
@@ -1,48 +1,65 @@
module minijson.cli;

import minijson.lib : minifyFiles, minifyString;
import minijson.lib : minifyFiles, minifyStrings;
import argparse;

import std.getopt : getopt, defaultGetoptPrinter, GetoptResult;
@(Command("minijson")
.Description(`minijson: minify json files with support for comments
/** Print help */
void printHelp(GetoptResult optResult) @trusted
{
return defaultGetoptPrinter(`minijson: minify json files with support for comments
minijson --file file1.json --file file2.json
minijson --file file1_with_comment.json --file file2_with_comment.json --comment
# Minify the specified files
minijson ./dist/**/*.json ./build/a.json
# Minify the specified files (supports comments)
minijson --comment file1_with_comment.json file2_with_comment.json
# Minify the specified json string
minijson --str '{"some_json": "string_here"}'
minijson --string '{"some_json": "string_here"}'
minijson --string '{"some_json": "string_here"} //comment' --comment
# Minify the specified json string (supports comments)
minijson --comment --str '{"some_json": "string_here"} //comment'
More information at https://github.com/aminya/minijson
`, optResult.options);
`)
)
struct Options
{
@TrailingArguments string[] files;
bool comment = false;
string[] str;
// (Deprecated) A list of files to minify (for backwards compatiblitity with getopt)
string[] file;
}

void main(string[] args) @trusted
int actualMain(Options opts) @trusted
{
string[] files;
string jsonString;
bool hasComment = false;
try
{
// minify the given files
if (opts.files.length > 0 || opts.file.length > 0)
{
const auto files = opts.files ~ opts.file;
minifyFiles(files, opts.comment);
}

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

if (optResult.helpWanted || (!files && !jsonString))
{
return printHelp(optResult);
}
minifyStrings(opts.str, opts.comment).each!writeln;

// minify the given files
if (files)
{
minifyFiles(files, hasComment);
}
}

// minify the given string and print to stdout
if (jsonString)
catch (Exception e)
{
import std : write;
import std.stdio : stderr;

write(minifyString(jsonString, hasComment));
stderr.writeln("Error: ", e.msg);
return 1;
}

return 0;
}

mixin CLI!Options.main!((args) { return actualMain(args); });
55 changes: 52 additions & 3 deletions src/native/lib.d
Original file line number Diff line number Diff line change
Expand Up @@ -162,17 +162,66 @@ private bool hasNoSpace(const ref string str) @trusted
}
}

/**
Minify the given JSON strings in parallel
Params:
jsonStrings = the json strings you want to minify
hasComment = a boolean to support comments in json. Default: `false`.
Return:
the minified json strings
*/
string[] minifyStrings(in string[] jsonStrings, in bool hasComment = false) @trusted
{
import std.algorithm: map;
import std.array: array;

return jsonStrings.map!(jsonString => minifyString(jsonString, hasComment)).array();
}

/**
Minify the given files in place. It minifies the files in parallel.
Params:
files = the paths to the files.
paths = the paths to the files. It could be glob patterns.
hasComment = a boolean to support comments in json. Default: `false`.
*/
void minifyFiles(in string[] files, in bool hasComment = false)
void minifyFiles(in string[] paths, in bool hasComment = false) @trusted
{
import std.parallelism : parallel;
import std.file : readText, write;
import std.algorithm;
import std.array;
import std.file : dirEntries, SpanMode, readText, write, isFile, isDir, exists;
import std.path : globMatch;
import glob : glob;
import std.stdio : writeln;

// get the files from the given paths (resolve glob patterns)
auto files = paths
.map!((path) {
if (path.exists)
{
if (path.isFile)
{
return [path];
}
else if (path.isDir)
{
return glob(path ~ "/**/*.json");
}
else
{
throw new Exception("The given path is not a file or a directory: " ~ path);
}
}
else
{
return glob(path);
}
})
.joiner()
.array();

foreach (file; files.parallel())
{
Expand Down
2 changes: 1 addition & 1 deletion src/node/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export async function minifyFiles(files: string[], hasComment = false): Promise<
* @throws {Promise<string | Error>} The promise is rejected with the reason for failure
*/
export async function minifyString(jsonString: string, hasComment = false): Promise<string> {
const args = ["--string", jsonString]
const args = ["--str", jsonString]
if (hasComment) {
args.push("--comment")
}
Expand Down

0 comments on commit 84787b6

Please sign in to comment.