find-cli 1.4.11 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,6 +56,16 @@ Options:
56
56
  --dry-run|-d Traverse the directories and files only
57
57
 
58
58
  --quietly|-q Do not show the directory and file path matching
59
+
60
+ --format|-f Formatted output, shown only once the search completes.
61
+
62
+ --glob|-g Treat the argument as a glob, which is the default.
63
+
64
+ --regex|-g Treat the argument as a regular expression.
65
+
66
+ --string|-s Treat the argument as a string.
67
+
68
+ --interactive|-i Interactive mode, allowing the argument to be provided via stdin.
59
69
  ```
60
70
 
61
71
  ### Setup
@@ -145,6 +155,39 @@ Here is a list of some of the conversions:
145
155
  Character classes and alternatives are also supported.
146
156
  Their conversions are more or less standard.
147
157
 
158
+ ### Command line considerations
159
+
160
+ Node is only supplied with the parsed command string and since shells remove double quotes, the following...
161
+
162
+ find -q "START_OF_CONTENT"
163
+
164
+ ...may as well be:
165
+
166
+ find -q START_OF_CONTENT
167
+
168
+ In either case the argument will be treated as a glob because Find does not see any double quotes.
169
+
170
+ There are two ways around this.
171
+
172
+ 1. You can use the interactive mode:
173
+
174
+ ```
175
+ find -qi
176
+ ```
177
+
178
+ This will allow you to input `"START_OF_CONTENT"` by hand, so to speak. Since Node is now reading `stdin` rather than a parsed command string, the quotes will remain.
179
+
180
+ 2. Use the `-s` flag:
181
+
182
+ ```
183
+ find -qs START_OF_CONTENT
184
+ ```
185
+
186
+ This coerces Find into treating the argument as a string irregardless of the missing double quotes.
187
+
188
+ There is also the `-r` flag for regular expressions if you do not want to type the `/` regular expression delimiters, by the way.
189
+ And lastly, the `-g` flag for globs is provided for the sake of completeness but since globs are the default it is never really needed.
190
+
148
191
  ## Contact
149
192
 
150
193
  * james.smith@djalbat.com
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
2
 
3
- const { HELP_OPTION, VERSION_OPTION, DRY_RUN_OPTION, QUIETLY_OPTION } = require("./options");
3
+ const { HELP_OPTION, GLOB_OPTION, REGEX_OPTION, STRING_OPTION, FORMAT_OPTION, VERSION_OPTION, DRY_RUN_OPTION, QUIETLY_OPTION, INTERACTIVE_OPTION } = require("./options");
4
4
 
5
5
  module.exports = {
6
6
  "h": HELP_OPTION,
7
+ "g": GLOB_OPTION,
8
+ "r": REGEX_OPTION,
9
+ "s": STRING_OPTION,
10
+ "f": FORMAT_OPTION,
7
11
  "v": VERSION_OPTION,
8
12
  "d": DRY_RUN_OPTION,
9
- "q": QUIETLY_OPTION
13
+ "q": QUIETLY_OPTION,
14
+ "i": INTERACTIVE_OPTION
10
15
  };
@@ -2,19 +2,23 @@
2
2
 
3
3
  const ruleOperation = require("../operation/rule"),
4
4
  findOperation = require("../operation/find"),
5
+ rulePromptOperation = require("../operation/prompt/rule"),
5
6
  readConfigurationOperation = require("../operation/readConfiguration");
6
7
 
7
8
  const { S, EMPTY_STRING } = require("../constants"),
8
9
  { executeOperations } = require("../utilities/operation");
9
10
 
10
- function findAction(string, dryRun, quietly) {
11
+ function findAction(string, dryRun, format, quietly, interactive) {
11
12
  const operations = [
12
13
  ruleOperation,
14
+ rulePromptOperation,
13
15
  readConfigurationOperation,
14
16
  findOperation
15
17
  ],
16
18
  rule = null,
17
19
  lines = [],
20
+ anchored = false,
21
+ directory = false,
18
22
  linesTotal = 0,
19
23
  filesTotal = 0,
20
24
  directoriesTotal = 0,
@@ -22,9 +26,13 @@ function findAction(string, dryRun, quietly) {
22
26
  context = {
23
27
  string,
24
28
  dryRun,
29
+ format,
25
30
  quietly,
31
+ interactive,
26
32
  rule,
27
33
  lines,
34
+ anchored,
35
+ directory,
28
36
  linesTotal,
29
37
  filesTotal,
30
38
  directoriesTotal,
@@ -32,13 +40,15 @@ function findAction(string, dryRun, quietly) {
32
40
  };
33
41
 
34
42
  executeOperations(operations, (completed) => {
35
- logLines(context);
43
+ if (format) {
44
+ logLines(context);
45
+ }
36
46
 
37
47
  if (!completed) {
38
48
  return;
39
49
  }
40
50
 
41
- logTottals(context);
51
+ logTotals(context);
42
52
  }, context);
43
53
  }
44
54
 
@@ -62,13 +72,13 @@ function logLines(context) {
62
72
  requiredContentLength = maximumContentLength; ///
63
73
 
64
74
  lines.forEach((line) => {
65
- const message = line.asMessage(requiredIndexLength, requiredContentLength);
75
+ const formattedMessage = line.asFormattedMessage(requiredIndexLength, requiredContentLength);
66
76
 
67
- console.log(message);
77
+ console.log(formattedMessage);
68
78
  });
69
79
  }
70
80
 
71
- function logTottals(context) {
81
+ function logTotals(context) {
72
82
  const { linesTotal, filesTotal, directoriesTotal, occurrencesTotal } = context,
73
83
  optionalS = (occurrencesTotal === 1) ?
74
84
  EMPTY_STRING :
@@ -29,6 +29,16 @@ Options:
29
29
 
30
30
  --quietly|-q Do not show the directory and file path matching
31
31
 
32
+ --format|-f Formatted output, shown only once the search completes.
33
+
34
+ --glob|-g Treat the argument as a glob, which is the default.
35
+
36
+ --regex|-g Treat the argument as a regular expression.
37
+
38
+ --string|-s Treat the argument as a string.
39
+
40
+ --interactive|-i Interactive mode, allowing the argument to be provided via stdin.
41
+
32
42
  Further information:
33
43
 
34
44
  Please see the readme file on GitHub:
package/bin/defaults.js CHANGED
@@ -1,13 +1,21 @@
1
1
  "use strict";
2
2
 
3
3
  const DEFAULT_HELP = false,
4
+ DEFAULT_REGEX = false,
5
+ DEFAULT_STRING = false,
6
+ DEFAULT_FORMAT = false,
4
7
  DEFAULT_VERSION = false,
5
8
  DEFAULT_DRY_RUN = false,
6
- DEFAULT_QUIETLY = false;
9
+ DEFAULT_QUIETLY = false,
10
+ DEFAULT_INTERACTIVE = false;
7
11
 
8
12
  module.exports = {
9
13
  DEFAULT_HELP,
14
+ DEFAULT_REGEX,
15
+ DEFAULT_STRING,
16
+ DEFAULT_FORMAT,
10
17
  DEFAULT_VERSION,
11
18
  DEFAULT_DRY_RUN,
12
- DEFAULT_QUIETLY
19
+ DEFAULT_QUIETLY,
20
+ DEFAULT_INTERACTIVE
13
21
  };
package/bin/find.js CHANGED
@@ -7,7 +7,7 @@ const Line = require("./line");
7
7
  const { readFile } = fileSystemUtilities;
8
8
 
9
9
  function find(filePath, context) {
10
- const { rule } = context,
10
+ const { rule, format } = context,
11
11
  content = readFile(filePath),
12
12
  lines = linesFromContentAndFilePath(content, filePath);
13
13
 
@@ -26,11 +26,17 @@ function find(filePath, context) {
26
26
  occurrencesTotal
27
27
  });
28
28
 
29
- const { lines } = context;
29
+ line.setOccurrences(occurrences);
30
30
 
31
- lines.push(line);
31
+ if (!format) {
32
+ const message = line.asMessage();
32
33
 
33
- line.setOccurrences(occurrences);
34
+ console.log(message);
35
+ } else {
36
+ const { lines } = context;
37
+
38
+ lines.push(line);
39
+ }
34
40
  }
35
41
 
36
42
  linesTotal++;
@@ -37,12 +37,18 @@ function asynchronousIsPathIgnored(path, directory, context, callback) {
37
37
  updatePathRulesOperation
38
38
  ],
39
39
  rule = null,
40
+ dryRun = false,
41
+ anchored = true,
42
+ interactive = true,
40
43
  pathIgnored = null;
41
44
 
42
45
  Object.assign(context, {
43
- rule,
44
46
  path,
45
47
  directory,
48
+ rule,
49
+ dryRun,
50
+ anchored,
51
+ interactive,
46
52
  pathIgnored
47
53
  });
48
54
 
package/bin/line.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const { arrayUtilities } = require("necessary");
4
4
 
5
- const { grey, blue, yellow, cyan } = require("./utilities/log"),
5
+ const { grey, blue, yellow } = require("./utilities/log"),
6
6
  { EMPTY_STRING, SINGLE_SPACE } = require("./constants");
7
7
 
8
8
  const { backwardsForEach } = arrayUtilities;
@@ -128,7 +128,7 @@ class Line {
128
128
 
129
129
  gap = grey(gap); ///
130
130
 
131
- match = cyan(match); ///
131
+ match = blue(match); ///
132
132
 
133
133
  string = `${string}${match}${gap}`;
134
134
  });
@@ -142,13 +142,18 @@ class Line {
142
142
  const filePathLength = this.getFilePathLength(),
143
143
  paddingLength = requiredFilePathLength - filePathLength,
144
144
  padding = paddingFromPaddingLength(paddingLength),
145
- filePath = `${this.filePath}${padding}`,
146
- formattedFilePath = blue(filePath);
145
+ formattedFilePath = `${this.filePath}${padding}`;
147
146
 
148
147
  return formattedFilePath;
149
148
  }
150
149
 
151
- asMessage(requiredIndexLength, requiredFilePathLength) {
150
+ asMessage() {
151
+ const message = `${this.filePath} ${this.index} | ${this.content}`;
152
+
153
+ return message;
154
+ }
155
+
156
+ asFormattedMessage(requiredIndexLength, requiredFilePathLength) {
152
157
  const formattedIndex = this.getFormattedIndex(requiredIndexLength),
153
158
  formattedContent = this.getFormattedContent(),
154
159
  formattedFilePath = this.getFormattedFilePath(requiredFilePathLength),
package/bin/main.js CHANGED
@@ -9,7 +9,7 @@ const findAction = require("./action/find"),
9
9
  removeRootDirectoryPathAction = require("./action/removeRootDirectoryPath");
10
10
 
11
11
  const { NO_ARGUMENT_GIVEN_MESSAGE, COMMAND_NOT_RECOGNISED_MESSAGE } = require("./messages"),
12
- { DEFAULT_DRY_RUN, DEFAULT_QUIETLY } = require("./defaults"),
12
+ { DEFAULT_REGEX, DEFAULT_STRING, DEFAULT_FORMAT, DEFAULT_DRY_RUN, DEFAULT_QUIETLY, DEFAULT_INTERACTIVE } = require("./defaults"),
13
13
  { FIND_COMMAND,
14
14
  HELP_COMMAND,
15
15
  VERSION_COMMAND,
@@ -19,7 +19,9 @@ const { NO_ARGUMENT_GIVEN_MESSAGE, COMMAND_NOT_RECOGNISED_MESSAGE } = require(".
19
19
  REMOVE_ROOT_DIRECTORY_PATH_COMMAND } = require("./commands");
20
20
 
21
21
  function main(command, argument, options) {
22
- const { dryRun = DEFAULT_DRY_RUN, quietly = DEFAULT_QUIETLY } = options;
22
+ const { format = DEFAULT_FORMAT, dryRun = DEFAULT_DRY_RUN, quietly = DEFAULT_QUIETLY, interactive = DEFAULT_INTERACTIVE } = options;
23
+
24
+ let { regex = DEFAULT_REGEX, string = DEFAULT_STRING } = options;
23
25
 
24
26
  switch (command) {
25
27
  case HELP_COMMAND: {
@@ -63,14 +65,26 @@ function main(command, argument, options) {
63
65
  }
64
66
 
65
67
  case FIND_COMMAND: {
66
- if ((argument === null) && !dryRun) {
67
- console.log(NO_ARGUMENT_GIVEN_MESSAGE);
68
- } else {
69
- const string = argument; ///
68
+ if (argument === null) {
69
+ if (!dryRun && !interactive) {
70
+ console.log(NO_ARGUMENT_GIVEN_MESSAGE);
71
+
72
+ break;
73
+ }
74
+ }
70
75
 
71
- findAction(string, dryRun, quietly);
76
+ if (false) {
77
+ ///
78
+ } else if (string) {
79
+ argument = `"${argument}"`;
80
+ } else if (regex) {
81
+ argument = `/${argument}/`;
72
82
  }
73
83
 
84
+ string = argument; ///
85
+
86
+ findAction(string, dryRun, format, quietly, interactive);
87
+
74
88
  break;
75
89
  }
76
90
 
@@ -100,11 +100,19 @@ function findInFile(filePath, callback, context) {
100
100
  const { quietly } = context;
101
101
 
102
102
  if (!quietly) {
103
- const { ruleString } = context;
103
+ let message;
104
104
 
105
- let message = filePathIgnored ?
106
- red(`Ignore ${filePath}`) :
107
- green(`Permit ${filePath}`);
105
+ const { format, ruleString } = context;
106
+
107
+ message = filePathIgnored ?
108
+ `Ignore ${filePath}`:
109
+ `Permit ${filePath}`;
110
+
111
+ if (format) {
112
+ message = filePathIgnored ?
113
+ red(message) :
114
+ green(message);
115
+ }
108
116
 
109
117
  message = `${message} ${ruleString}`;
110
118
 
@@ -157,11 +165,19 @@ function findInDirectory(directoryPath, callback, context) {
157
165
  const { quietly } = context;
158
166
 
159
167
  if (!quietly) {
160
- const { ruleString } = context;
168
+ let message;
169
+
170
+ const { format, ruleString } = context;
171
+
172
+ message = directoryPathIgnored ?
173
+ `Ignore ${directoryPath}/` :
174
+ `Permit ${directoryPath}/`;
161
175
 
162
- let message = directoryPathIgnored ?
163
- red(`Ignore ${directoryPath}/`) :
164
- green(`Permit ${directoryPath}/`);
176
+ if (format) {
177
+ message = directoryPathIgnored ?
178
+ red(message) :
179
+ green(message);
180
+ }
165
181
 
166
182
  message = `${message} ${ruleString}`;
167
183
 
@@ -2,20 +2,36 @@
2
2
 
3
3
  const { shellUtilities } = require("necessary");
4
4
 
5
- const { ruleFromStringAnchoredAndDirectory } = require("../../utilities/rule"),
6
- { validateGlobStringOrPattern } = require("../../utilities/validate"),
5
+ const { validateGlobStringOrPattern } = require("../../utilities/validate"),
7
6
  { GLOB_STRING_OR_REGEX_DESCRIPTION } = require("../../descriptions"),
7
+ { ruleFromStringAnchoredAndDirectory } = require("../../utilities/rule"),
8
8
  { INVALID_GLOB_REGEX_OR_STRING_MESSAGE } = require("../../messages");
9
9
 
10
10
  const { prompt } = shellUtilities;
11
11
 
12
12
  function rulePromptOperation(proceed, abort, context) {
13
- const { path, directory } = context,
13
+ const { dryRun } = context;
14
+
15
+ if (dryRun) {
16
+ proceed();
17
+
18
+ return;
19
+ }
20
+
21
+ const { interactive } = context;
22
+
23
+ if (!interactive) {
24
+ proceed();
25
+
26
+ return;
27
+ }
28
+
29
+ const { path, anchored, directory } = context,
14
30
  description = GLOB_STRING_OR_REGEX_DESCRIPTION,
15
31
  errorMessage = INVALID_GLOB_REGEX_OR_STRING_MESSAGE,
16
32
  initialAnswer = path, ///
17
33
  validationFunction = (answer) => {
18
- const valid = validateGlobStringOrPattern(answer, directory);
34
+ const valid = validateGlobStringOrPattern(answer, anchored, directory);
19
35
 
20
36
  return valid;
21
37
  },
@@ -36,7 +52,6 @@ function rulePromptOperation(proceed, abort, context) {
36
52
  }
37
53
 
38
54
  const string = answer, ///
39
- anchored = true,
40
55
  rule = ruleFromStringAnchoredAndDirectory(string, anchored, directory);
41
56
 
42
57
  Object.assign(context, {
@@ -11,9 +11,15 @@ function ruleOperation(proceed, abort, context) {
11
11
  return;
12
12
  }
13
13
 
14
- const { string } = context,
15
- directory = false,
16
- anchored = false,
14
+ const { interactive } = context;
15
+
16
+ if (interactive) {
17
+ proceed();
18
+
19
+ return;
20
+ }
21
+
22
+ const { string, anchored, directory } = context,
17
23
  rule = ruleFromStringAnchoredAndDirectory(string, anchored, directory);
18
24
 
19
25
  if (rule === null) {
package/bin/options.js CHANGED
@@ -1,13 +1,23 @@
1
1
  "use strict";
2
2
 
3
3
  const HELP_OPTION = "help",
4
+ GLOB_OPTION = "glob",
5
+ REGEX_OPTION = "regex",
6
+ STRING_OPTION = "string",
7
+ FORMAT_OPTION = "format",
4
8
  VERSION_OPTION = "version",
5
9
  QUIETLY_OPTION = "quietly",
6
- DRY_RUN_OPTION = "dry-run";
10
+ DRY_RUN_OPTION = "dry-run",
11
+ INTERACTIVE_OPTION = "interactive";
7
12
 
8
13
  module.exports = {
9
14
  HELP_OPTION,
15
+ GLOB_OPTION,
16
+ REGEX_OPTION,
17
+ STRING_OPTION,
18
+ FORMAT_OPTION,
10
19
  VERSION_OPTION,
11
20
  QUIETLY_OPTION,
12
- DRY_RUN_OPTION
21
+ DRY_RUN_OPTION,
22
+ INTERACTIVE_OPTION
13
23
  };
@@ -3,10 +3,8 @@
3
3
  const RED_FOREGROUND_COLOUR = "\u001b[31m",
4
4
  GREY_FOREGROUND_COLOUR = "\u001b[90m",
5
5
  BLUE_FOREGROUND_COLOUR = "\u001b[34m",
6
- CYAN_FOREGROUND_COLOUR = "\u001b[36m",
7
6
  GREEN_FOREGROUND_COLOUR = "\u001b[32m",
8
7
  YELLOW_FOREGROUND_COLOUR = "\u001b[33m",
9
- MAGENTA_FOREGROUND_COLOUR = "\u001b[35m",
10
8
  RESET_FOREGROUND_COLOUR = "\u001b[39m";
11
9
 
12
10
  function red(string) { return `${RED_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
@@ -15,20 +13,14 @@ function grey(string) { return `${GREY_FOREGROUND_COLOUR}${string}${RESET_FOREGR
15
13
 
16
14
  function blue(string) { return `${BLUE_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
17
15
 
18
- function cyan(string) { return `${CYAN_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
19
-
20
16
  function green(string) { return `${GREEN_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
21
17
 
22
18
  function yellow(string) { return `${YELLOW_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
23
19
 
24
- function magenta(string) { return `${MAGENTA_FOREGROUND_COLOUR}${string}${RESET_FOREGROUND_COLOUR}`; }
25
-
26
20
  module.exports = {
27
21
  red,
28
22
  grey,
29
23
  blue,
30
- cyan,
31
24
  green,
32
- yellow,
33
- magenta
25
+ yellow
34
26
  };
@@ -39,9 +39,8 @@ function validateRootDirectoryPath(answer) {
39
39
  return valid;
40
40
  }
41
41
 
42
- function validateGlobStringOrPattern(answer, directory) {
42
+ function validateGlobStringOrPattern(answer, anchored, directory) {
43
43
  const string = answer, ///
44
- anchored = false,
45
44
  rule = ruleFromStringAnchoredAndDirectory(string, anchored, directory),
46
45
  valid = (rule !== null)
47
46
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "find-cli",
3
3
  "author": "James Smith",
4
- "version": "1.4.11",
4
+ "version": "1.6.2",
5
5
  "license": "MIT, Anti-996",
6
6
  "homepage": "https://github.com/djalbat/find-cli",
7
7
  "description": "An alternative to grep.",