misc/importsort-d

src/main.d in v0.3.0
Repositories | Summary | Log | Files | README.md

main.d (4297B) download


  1// (c) 2022 Friedel Schon <[email protected]>
  2
  3module importsort.main;
  4
  5import core.stdc.stdlib : exit;
  6import importsort.sort : Import, SortConfig, sortImports;
  7import std.array : replace;
  8import std.conv : ConvException, parse;
  9import std.file : DirEntry, SpanMode, dirEntries, exists, isDir, isFile;
 10import std.functional : unaryFun;
 11import std.stdio : File, stderr, stdin, stdout;
 12import std.string : endsWith;
 13
 14enum BINARY = "importsort-d";
 15enum VERSION = "0.1.0";
 16enum HELP = import("help.txt")
 17		.replace("{binary}", BINARY)
 18		.replace("{version}", VERSION);
 19
 20DirEntry[] listEntries(alias F = "true")(string[] input, bool recursive) {
 21	alias filterFunc = unaryFun!F;
 22
 23	DirEntry[] entries;
 24
 25	foreach (path; input) {
 26		if (!exists(path)) {
 27			stderr.writef("error: '%s' does not exist\n", path);
 28			exit(1);
 29		} else if (isDir(path)) {
 30			foreach (entry; dirEntries(path, recursive ? SpanMode.depth : SpanMode.shallow)) {
 31				if (entry.isFile && entry.name.endsWith(".d") && filterFunc(entry.name))
 32					entries ~= entry;
 33			}
 34		} else if (isFile(path)) {
 35			if (!path.endsWith(".d")) {
 36				stderr.writef("error: '%s' is not a .d-file\n", path);
 37				exit(1);
 38			}
 39			if (filterFunc(path))
 40				entries ~= DirEntry(path);
 41		} else {
 42			stderr.writef("error: '%s' is not a file or directory\n", path);
 43			exit(1);
 44		}
 45	}
 46	return entries;
 47}
 48
 49void main(string[] args) {
 50	SortConfig config;
 51	bool inline;
 52	string output;
 53	string[] input;
 54	bool watcher;
 55	bool watcherDelaySet;
 56	double watcherDelay = 0.1; // sec
 57	bool recursive;
 58
 59	// -*- option parser -*-
 60
 61	bool nextOutput;
 62	bool nextWatcherDelay;
 63	foreach (arg; args[1 .. $]) {
 64		if (nextOutput) {
 65			output = arg;
 66			nextOutput = false;
 67		} else if (nextWatcherDelay) {
 68			try {
 69				watcherDelay = parse!double(arg);
 70			} catch (ConvException) {
 71				stderr.writef("error: cannot parse delay '%s' to an integer\n", arg);
 72				exit(1);
 73			}
 74			watcherDelaySet = true;
 75			nextWatcherDelay = false;
 76		} else if (arg == "--help" || arg == "-h") {
 77			stdout.writeln(HELP);
 78			return;
 79		} else if (arg == "--verbose" || arg == "-v") {
 80			config.verbose = true;
 81		} else if (arg == "--keep" || arg == "-k") {
 82			config.keepLine = true;
 83		} else if (arg == "--attribute" || arg == "-a") {
 84			config.byAttribute = true;
 85		} else if (arg == "--binding" || arg == "-b") {
 86			config.byBinding = true;
 87		} else if (arg == "--merge" || arg == "-m") {
 88			config.merge = true;
 89		} else if (arg == "--inline" || arg == "-i") {
 90			inline = true;
 91		} else if (arg == "--recursive" || arg == "-r") {
 92			recursive = true;
 93			// TODO: --watch
 94			/*} else if (arg == "--watch" || arg == "-w") {
 95			watcher = true;
 96		} else if (arg == "--delay" || arg == "-d") {
 97			if (watcherDelaySet) {
 98				stderr.writeln("error: watcher-delay already specified");
 99				stderr.writeln(HELP);
100				exit(1);
101			}
102			nextWatcherDelay = true;*/
103		} else if (arg == "--output" || arg == "-o") {
104			if (output != null) {
105				stderr.writeln("error: output already specified");
106				stderr.writeln(HELP);
107				exit(1);
108			}
109			nextOutput = true;
110		} else if (arg[0] == '-') {
111			stderr.writef("error: unknown option '%s'\n", arg);
112			stderr.writeln(HELP);
113			exit(1);
114		} else {
115			input ~= arg;
116		}
117	}
118	if (recursive && input.length == 0) {
119		stderr.writeln("error: cannot use '--recursive' and specify no input");
120		exit(1);
121	}
122	if (inline && input.length == 0) {
123		stderr.writeln("error: cannot use '--inline' and read from stdin");
124		exit(1);
125	}
126	if ((!inline || output.length > 0) && input.length > 0) {
127		stderr.writeln("error: if you use inputs you must use '--inline'");
128		exit(1);
129	}
130	// -*- operation -*-
131
132	/*	if (watcher) {
133		stderr.writeln("\033[1;34mwatching files...\033[0m");
134		SysTime[string] lastModified;
135		for (;;) {
136			auto entries = listEntries!(x => x !in lastModified
137					|| lastModified[x] != x.timeLastModified)(input, recursive);
138
139			foreach (entry; entries) {
140				lastModified[entry.name] = entry.timeLastModified;
141			}
142			entries.sortImports(config);
143			Thread.sleep(Duration!"msecs"(cast(long) watcherDelay * 1000));
144		}
145	} else 
146	*/
147	if (input == null) {
148		File outfile = (output == null) ? stdout : File(output);
149
150		sortImports(stdin, outfile, config);
151		if (output)
152			outfile.close();
153	} else {
154		listEntries(input, recursive).sortImports(config);
155	}
156}