importsort-d

Sort and format imports in DLang
Log | Files | Refs | README

commit 7726d38296a3ceee136ddc3858fc6ec1d95847e2
parent b4745146b4af1a327d3509d55643986fb7eaa5b8
Author: Friedel Schoen <[email protected]>
Date:   Mon, 10 Oct 2022 00:31:51 +0200

moving from GNU make to DUB

Diffstat:
DMakefile | 11-----------
MREADME.md | 15+++++++--------
Adub.sdl | 10++++++++++
Dimportsort.d | 153-------------------------------------------------------------------------------
Asrc/main.d | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 170 insertions(+), 172 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,10 +0,0 @@ -DMD := dmd -DMDFLAGS := - -.PHONY: install - -importsort-d: - dmd -of=importsort-d importsort.d - -install: importsort-d - install importsort-d /usr/bin/ -\ No newline at end of file diff --git a/README.md b/README.md @@ -1,27 +1,26 @@ # Sort Imports for [*D*](https://dlang.org/) -> `sortimport-d` can sort your dozens of `import`'s in a `.d` file (no matter where) +`sortimport-d` can sort your dozens of `import`'s in a `.d` file (no matter where) ## Installation ### Prerequirements -- [`make`](https://www.gnu.org/software/make/) +- [`dub`](https://dub.pm/) - [`dmd`](https://dlang.org/) ### Building -Get the repository with `git`: +Get the repository with `git` and compile everything with `dub` ``` $ git clone https://github.com/friedelschoen/importsort-d $ cd importsort-d +$ dub build ``` -And finally build this project with -``` -$ make -# make install -``` +If everything went fine, there should be a binary at `bin/importsort-d`. + +Copy this into a directory included in `$PATH` (`/usr/bin` for example) to make this command working global. ## Usage diff --git a/dub.sdl b/dub.sdl @@ -0,0 +1,9 @@ +name "importsort-d" +description "sort imports of a .d-file" +authors "Friedel Schoen" +copyright "Copyright © 2022, Friedel Schoen" +license "zlib" + +targetType "executable" +targetPath "bin" +targetName "importsort-d" +\ No newline at end of file diff --git a/importsort.d b/importsort.d @@ -1,153 +0,0 @@ -// (c) 2022 Friedel Schon <[email protected]> - -module importsort; - -import core.stdc.stdlib : exit; -import std.algorithm : map, sort; -import std.array : array; -import std.file : copy, remove; -import std.range : empty; -import std.regex : ctRegex, matchFirst; -import std.stdio : File, stderr, stdin, stdout; -import std.string : format, split, strip, stripLeft; -import std.typecons : Yes; - -struct Import { - string name; - string[] indents; - - string begin; - string end; -} - -const pattern = ctRegex!`^([ \t]*)import[ \t]+([a-zA-Z._]+)[ \t]*(:[ \t]*\w+(?:[ \t]*,[ \t]*\w+)*)?[ \t]*;[ \t]*([\n\r]*)$`; - -const help = (string arg0) => "Usage: %s [options] [path] - <path> can be ommitted or set to '-' to read from stdin - -Options: - -k, --keep ....... keeps a backup if using '--inline' - -i, --inline ..... changes the input - -o, --out <path> . writes to `path` instead of stdout".format(arg0); - -void main(string[] args) { - bool inline = false; - bool keep = false; - string output = null; - string path = null; - - bool nextout = false; - - foreach (arg; args[1 .. $]) { - if (nextout) { - output = arg; - nextout = false; - } - if (arg == "--help" || arg == "-h") { - stdout.writeln(help(args[0])); - return; - } - if (arg == "--keep" || arg == "-k") { - keep = true; - } else if (arg == "--inline" || arg == "-i") { - inline = true; - } else if (arg == "--out" || arg == "-o") { - if (output != null) { - stderr.writeln("error: output already specified"); - stderr.writeln(help(args[0])); - exit(1); - } - nextout = true; - } else { - if (path != null) { - stderr.writeln("error: input already specified"); - stderr.writeln(help(args[0])); - exit(1); - } - path = arg; - } - } - if (output != null && output == path) { - stderr.writeln("error: input and output cannot be the same; use '--inline'"); - stderr.writeln(help(args[0])); - exit(1); - } - if (!inline && keep) { - stderr.writeln("error: you have to specify '--keep' in combination with '--inline'"); - exit(1); - } - if (inline && output != null) { - stderr.writeln("error: you cannot specify '--inline' and '--out' at the same time"); - exit(1); - } - if (!path) { - path = "-"; - } - if (inline && path == "-") { - stderr.writeln("error: you cannot specify '--inline' and read from stdin"); - exit(1); - } - - File infile, outfile; - if (inline) { - copy(path, path ~ ".bak"); - infile = File(path ~ ".bak"); - } else if (path == "-") { - infile = stdin; - } else { - infile = File(path); - } - - if (inline) - outfile = File(path, "w"); - else if (output) - outfile = File(output, "w"); - else - outfile = stdout; - - string softEnd = null; - Import[] matches; - foreach (line; infile.byLine(Yes.keepTerminator)) { - auto match = matchFirst(line, pattern); - if (!match.empty) { // is import - if (softEnd) { - if (matches.empty) - outfile.write(softEnd); - softEnd = null; - } - string[] idents = match[3][1 .. $].split(",").map!(x => x.idup.strip).array; - idents.sort(); - matches ~= Import(match[2].idup, idents, match[1].idup, match[4].idup); - } else { - if (!softEnd && line.stripLeft == "") { - softEnd = line.idup; - } else { - if (!matches.empty) { - matches.sort!((a, b) => a.name < b.name); - foreach (m; matches) { - outfile.writef("%simport %s", m.begin, m.name); - foreach (i, ident; m.indents) { - auto begin = i == 0 ? " : " : ", "; - outfile.write(begin ~ ident); - } - outfile.writef(";%s", m.end); - } - - matches = []; - } - if (softEnd) { - outfile.write(softEnd); - softEnd = null; - } - outfile.write(line); - } - } - } - - infile.close(); - - if (inline && !keep) - remove(path ~ ".bak"); - - outfile.close(); -} diff --git a/src/main.d b/src/main.d @@ -0,0 +1,153 @@ +// (c) 2022 Friedel Schon <[email protected]> + +module source.main; + +import core.stdc.stdlib : exit; +import std.algorithm : map, sort; +import std.array : array; +import std.file : copy, remove; +import std.range : empty; +import std.regex : ctRegex, matchFirst; +import std.stdio : File, stderr, stdin, stdout; +import std.string : format, split, strip, stripLeft; +import std.typecons : Yes; + +struct Import { + string name; + string[] indents; + + string begin; + string end; +} + +const pattern = ctRegex!`^([ \t]*)import[ \t]+([a-zA-Z._]+)[ \t]*(:[ \t]*\w+(?:[ \t]*,[ \t]*\w+)*)?[ \t]*;[ \t]*([\n\r]*)$`; + +const help = (string arg0) => "Usage: %s [options] [path] + <path> can be ommitted or set to '-' to read from stdin + +Options: + -k, --keep ....... keeps a backup if using '--inline' + -i, --inline ..... changes the input + -o, --out <path> . writes to `path` instead of stdout".format(arg0); + +void main(string[] args) { + bool inline = false; + bool keep = false; + string output = null; + string path = null; + + bool nextout = false; + + foreach (arg; args[1 .. $]) { + if (nextout) { + output = arg; + nextout = false; + } + if (arg == "--help" || arg == "-h") { + stdout.writeln(help(args[0])); + return; + } + if (arg == "--keep" || arg == "-k") { + keep = true; + } else if (arg == "--inline" || arg == "-i") { + inline = true; + } else if (arg == "--out" || arg == "-o") { + if (output != null) { + stderr.writeln("error: output already specified"); + stderr.writeln(help(args[0])); + exit(1); + } + nextout = true; + } else { + if (path != null) { + stderr.writeln("error: input already specified"); + stderr.writeln(help(args[0])); + exit(1); + } + path = arg; + } + } + if (output != null && output == path) { + stderr.writeln("error: input and output cannot be the same; use '--inline'"); + stderr.writeln(help(args[0])); + exit(1); + } + if (!inline && keep) { + stderr.writeln("error: you have to specify '--keep' in combination with '--inline'"); + exit(1); + } + if (inline && output != null) { + stderr.writeln("error: you cannot specify '--inline' and '--out' at the same time"); + exit(1); + } + if (!path) { + path = "-"; + } + if (inline && path == "-") { + stderr.writeln("error: you cannot specify '--inline' and read from stdin"); + exit(1); + } + + File infile, outfile; + if (inline) { + copy(path, path ~ ".bak"); + infile = File(path ~ ".bak"); + } else if (path == "-") { + infile = stdin; + } else { + infile = File(path); + } + + if (inline) + outfile = File(path, "w"); + else if (output) + outfile = File(output, "w"); + else + outfile = stdout; + + string softEnd = null; + Import[] matches; + foreach (line; infile.byLine(Yes.keepTerminator)) { + auto match = matchFirst(line, pattern); + if (!match.empty) { // is import + if (softEnd) { + if (matches.empty) + outfile.write(softEnd); + softEnd = null; + } + string[] idents = match[3][1 .. $].split(",").map!(x => x.idup.strip).array; + idents.sort(); + matches ~= Import(match[2].idup, idents, match[1].idup, match[4].idup); + } else { + if (!softEnd && line.stripLeft == "") { + softEnd = line.idup; + } else { + if (!matches.empty) { + matches.sort!((a, b) => a.name < b.name); + foreach (m; matches) { + outfile.writef("%simport %s", m.begin, m.name); + foreach (i, ident; m.indents) { + auto begin = i == 0 ? " : " : ", "; + outfile.write(begin ~ ident); + } + outfile.writef(";%s", m.end); + } + + matches = []; + } + if (softEnd) { + outfile.write(softEnd); + softEnd = null; + } + outfile.write(line); + } + } + } + + infile.close(); + + if (inline && !keep) + remove(path ~ ".bak"); + + outfile.close(); +}