find-cli 1.4.3 → 1.4.5

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.
@@ -4,7 +4,8 @@ const ruleOperation = require("../operation/rule"),
4
4
  findOperation = require("../operation/find"),
5
5
  readConfigurationOperation = require("../operation/readConfiguration");
6
6
 
7
- const { executeOperations } = require("../utilities/operation"),
7
+ const { S, EMPTY_STRING } = require("../constants"),
8
+ { executeOperations } = require("../utilities/operation"),
8
9
  { FAILED_FIND_MESSAGE, SUCCESSFUL_FIND_MESSAGE } = require("../messages");
9
10
 
10
11
  function findAction(string, dryRun, quietly) {
@@ -14,24 +15,25 @@ function findAction(string, dryRun, quietly) {
14
15
  findOperation
15
16
  ],
16
17
  rule = null,
17
- totalLines = 0,
18
- totalFiles = 0,
19
- totalDirectories = 0,
18
+ lines = [],
19
+ linesTotal = 0,
20
+ filesTotal = 0,
21
+ directoriesTotal = 0,
22
+ occurrencesTotal = 0,
20
23
  context = {
21
24
  string,
22
25
  dryRun,
23
26
  quietly,
24
27
  rule,
25
- totalLines,
26
- totalFiles,
27
- totalDirectories
28
+ lines,
29
+ linesTotal,
30
+ filesTotal,
31
+ directoriesTotal,
32
+ occurrencesTotal
28
33
  };
29
34
 
30
35
  executeOperations(operations, (completed) => {
31
- const { totalLines, totalFiles, totalDirectories } = context,
32
- message = `A total of ${totalDirectories} directories, ${totalFiles} files and ${totalLines} lines searched.`;
33
-
34
- console.log(message);
36
+ logTottals(context);
35
37
 
36
38
  if (!completed) {
37
39
  console.log(FAILED_FIND_MESSAGE);
@@ -39,8 +41,44 @@ function findAction(string, dryRun, quietly) {
39
41
  return;
40
42
  }
41
43
 
44
+ logLines(context);
45
+
42
46
  console.log(SUCCESSFUL_FIND_MESSAGE);
43
47
  }, context);
44
48
  }
45
49
 
46
50
  module.exports = findAction;
51
+
52
+ function logLines(context) {
53
+ const { lines } = context;
54
+
55
+ let maximumIndexLength = 0,
56
+ maximumContentLength = 0;
57
+
58
+ lines.forEach((line) => {
59
+ const indexLength = line.getIndexLength(),
60
+ filePathLength = line.getFilePathLength();
61
+
62
+ maximumIndexLength = Math.max(indexLength, maximumIndexLength);
63
+ maximumContentLength = Math.max(filePathLength, maximumContentLength);
64
+ });
65
+
66
+ const requiredIndexLength = maximumIndexLength, ///
67
+ requiredContentLength = maximumContentLength; ///
68
+
69
+ lines.forEach((line) => {
70
+ const message = line.asMessage(requiredIndexLength, requiredContentLength);
71
+
72
+ console.log(message);
73
+ });
74
+ }
75
+
76
+ function logTottals(context) {
77
+ const { linesTotal, filesTotal, directoriesTotal, occurrencesTotal } = context,
78
+ optionalS = (occurrencesTotal === 1) ?
79
+ EMPTY_STRING :
80
+ S,
81
+ message = `Found ${occurrencesTotal} occurrence${optionalS} across ${directoriesTotal} directories, ${filesTotal} files and ${linesTotal} lines.`;
82
+
83
+ console.log(message);
84
+ }
package/bin/constants.js CHANGED
@@ -1,19 +1,25 @@
1
1
  "use strict";
2
2
 
3
- const FIND = "find",
3
+ const S = "s",
4
+ ZERO = 0,
5
+ FIND = "find",
4
6
  FILE = "file",
5
7
  G_FLAG = "g",
6
8
  FIND_CLI = "Find-CLI",
7
9
  DIRECTORY = "directory",
8
10
  EMPTY_STRING = "",
11
+ SINGLE_SPACE = " ",
9
12
  ROOT_DIRECTORY_PATH = "./";
10
13
 
11
14
  module.exports = {
15
+ S,
16
+ ZERO,
12
17
  FIND,
13
18
  FILE,
14
19
  G_FLAG,
15
20
  FIND_CLI,
16
21
  DIRECTORY,
17
22
  EMPTY_STRING,
23
+ SINGLE_SPACE,
18
24
  ROOT_DIRECTORY_PATH
19
25
  };
package/bin/find.js CHANGED
@@ -1,118 +1,55 @@
1
1
  "use strict";
2
2
 
3
- const { arrayUtilities, fileSystemUtilities } = require("necessary");
3
+ const { fileSystemUtilities } = require("necessary");
4
4
 
5
- const { grey, blue } = require("./utilities/log"),
6
- { EMPTY_STRING } = require("./constants");
5
+ const Line = require("./line");
7
6
 
8
- const { readFile } = fileSystemUtilities,
9
- { backwardsForEach } = arrayUtilities;
7
+ const { readFile } = fileSystemUtilities;
10
8
 
11
9
  function find(filePath, context) {
12
10
  const { rule } = context,
13
11
  content = readFile(filePath),
14
- lines = linesFromContent(content);
12
+ lines = linesFromContentAndFilePath(content, filePath);
15
13
 
16
- let { totalLines } = context;
14
+ let { linesTotal } = context;
17
15
 
18
- lines.forEach((line, index) => {
19
- const string = line, ///
20
- occurrences = rule.find(string),
21
- length = occurrences.length;
16
+ lines.forEach((line) => {
17
+ const occurrences = rule.find(line, filePath),
18
+ occurrencesLength = occurrences.length;
22
19
 
23
- if (length > 0) {
24
- const gaps = [],
25
- matches = [];
20
+ if (occurrencesLength > 0) {
21
+ let { occurrencesTotal } = context;
26
22
 
27
- gapsAndMatchesFromLineAndOccurrences(line, occurrences, gaps, matches);
23
+ occurrencesTotal += occurrencesLength;
28
24
 
29
- line = lineFromGapsAndMatches(gaps, matches); ///
25
+ Object.assign(context, {
26
+ occurrencesTotal
27
+ });
30
28
 
31
- console.log(filePath, index, line);
29
+ const { lines } = context;
30
+
31
+ lines.push(line);
32
+
33
+ line.setOccurrences(occurrences);
32
34
  }
33
35
 
34
- totalLines++;
36
+ linesTotal++;
35
37
  });
36
38
 
37
39
  Object.assign(context, {
38
- totalLines
40
+ linesTotal
39
41
  });
40
42
  }
41
43
 
42
44
  module.exports = find;
43
45
 
44
- function linesFromContent(content) {
46
+ function linesFromContentAndFilePath(content, filePath) {
45
47
  const contents = content.split(/(\r\n|\r|\n)/),
46
- lines = contents.map((content) => {
47
- const line = content.replace(/(\r\n|\r|\n)$/, EMPTY_STRING);
48
+ lines = contents.map((content, index) => {
49
+ const line = Line.fromIndexContentAndFilePath(index, content, filePath);
48
50
 
49
51
  return line;
50
52
  });
51
53
 
52
54
  return lines;
53
55
  }
54
-
55
- function lineFromGapsAndMatches(gaps, matches) {
56
- let line = EMPTY_STRING;
57
-
58
- gaps = [ ...gaps ]; ///
59
-
60
- let gap = gaps.pop(); ///
61
-
62
- gaps.forEach((gap, index) => {
63
- let match = matches[index];
64
-
65
- gap = grey(gap); ///
66
-
67
- match = blue(match); ///
68
-
69
- line = `${line}${gap}${match}`;
70
- });
71
-
72
- gap = grey(gap); ///
73
-
74
- line = `${line}${gap}`;
75
-
76
- return line;
77
- }
78
-
79
- function gapsAndMatchesFromLineAndOccurrences(line, occurrences, gaps, matches) {
80
- let end,
81
- start;
82
-
83
- backwardsForEach(occurrences, (occurrence) => {
84
- end = occurrence.getEnd();
85
-
86
- start = end; ///
87
-
88
- end = Infinity;
89
-
90
- const gap = line.substring(start, end);
91
-
92
- gaps.unshift(gap);
93
-
94
- end = occurrence.getEnd();
95
-
96
- start = 0;
97
-
98
- line = line.substring(start, end);
99
-
100
- start = occurrence.getStart();
101
-
102
- end = Infinity;
103
-
104
- const match = line.substring(start, end);
105
-
106
- matches.unshift(match);
107
-
108
- end = start; ///
109
-
110
- start = 0;
111
-
112
- line = line.substring(start, end); ///
113
- });
114
-
115
- const gap = line; ///
116
-
117
- gaps.unshift(gap);
118
- }
package/bin/line.js ADDED
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+
3
+ const { arrayUtilities } = require("necessary");
4
+
5
+ const { grey, blue, yellow } = require("./utilities/log"),
6
+ { EMPTY_STRING, SINGLE_SPACE } = require("./constants");
7
+
8
+ const { backwardsForEach } = arrayUtilities;
9
+
10
+ class Line {
11
+ constructor(index, content, filePath, occurrences) {
12
+ this.index = index;
13
+ this.content = content;
14
+ this.filePath = filePath;
15
+ this.occurences = occurrences;
16
+ }
17
+
18
+ getIndex() {
19
+ return this.index;
20
+ }
21
+
22
+ getContent() {
23
+ return this.content;
24
+ }
25
+
26
+ getFilePath() {
27
+ return this.filePath;
28
+ }
29
+
30
+ getOccurrences() {
31
+ return this.occurences;
32
+ }
33
+
34
+ setIndex(index) {
35
+ this.index = index;
36
+ }
37
+
38
+ setContent(content) {
39
+ this.content = content;
40
+ }
41
+
42
+ setFilePath(filePath) {
43
+ this.filePath = filePath;
44
+ }
45
+
46
+ setOccurrences(occurrences) {
47
+ this.occurrences = occurrences;
48
+ }
49
+
50
+ getIndexLength() {
51
+ const indexLength = this.index.length;
52
+
53
+ return indexLength;
54
+ }
55
+
56
+ getFilePathLength() {
57
+ const filePathLength = this.filePath.length;
58
+
59
+ return filePathLength;
60
+ }
61
+
62
+ addOccurrences(occurrences) {
63
+
64
+ }
65
+
66
+ getFormattedIndex(requiredIndexLength) {
67
+ let index;
68
+
69
+ const indexLength = this.getIndexLength(),
70
+ paddingLength = requiredIndexLength - indexLength,
71
+ padding = paddingFromPaddingLength(paddingLength);
72
+
73
+ index = `${padding}${this.index}`;
74
+
75
+ const formattedIndex = yellow(index);
76
+
77
+ return formattedIndex;
78
+ }
79
+
80
+ getFormattedContent() {
81
+ const gaps = [],
82
+ matches = [];
83
+
84
+ let end,
85
+ start,
86
+ string = this.content; ///
87
+
88
+ backwardsForEach(this.occurrences, (occurrence) => {
89
+ end = occurrence.getEnd();
90
+
91
+ start = end; ///
92
+
93
+ end = Infinity;
94
+
95
+ const gap = string.substring(start, end);
96
+
97
+ gaps.unshift(gap);
98
+
99
+ end = occurrence.getEnd();
100
+
101
+ start = 0;
102
+
103
+ string = string.substring(start, end);
104
+
105
+ start = occurrence.getStart();
106
+
107
+ end = Infinity;
108
+
109
+ const match = string.substring(start, end);
110
+
111
+ matches.unshift(match);
112
+
113
+ end = start; ///
114
+
115
+ start = 0;
116
+
117
+ string = string.substring(start, end); ///
118
+ });
119
+
120
+ let gap = string; ///
121
+
122
+ gap = grey(gap); ///
123
+
124
+ string = gap; ///
125
+
126
+ gaps.forEach((gap, index) => {
127
+ let match = matches[index];
128
+
129
+ gap = grey(gap); ///
130
+
131
+ match = blue(match); ///
132
+
133
+ string = `${string}${match}${gap}`;
134
+ });
135
+
136
+ const formattedContent = string; ///
137
+
138
+ return formattedContent;
139
+ }
140
+
141
+ getFormattedFilePath(requiredFilePathLength) {
142
+ const filePathLength = this.getFilePathLength(),
143
+ paddingLength = requiredFilePathLength - filePathLength,
144
+ padding = paddingFromPaddingLength(paddingLength),
145
+ formattedFilePath = `${this.filePath}${padding}`;
146
+
147
+ return formattedFilePath;
148
+ }
149
+
150
+ asMessage(requiredIndexLength, requiredFilePathLength) {
151
+ const formattedIndex = this.getFormattedIndex(requiredIndexLength),
152
+ formattedContent = this.getFormattedContent(),
153
+ formattedFilePath = this.getFormattedFilePath(requiredFilePathLength),
154
+ message = `| ${formattedFilePath} ${formattedIndex} | ${formattedContent}`;
155
+
156
+ return message;
157
+ }
158
+
159
+ static fromIndexContentAndFilePath(index, content, filePath) {
160
+ index = `${index}`; ///
161
+
162
+ content = content.replace(/(\r\n|\r|\n)$/, EMPTY_STRING); ///
163
+
164
+ const occurrences = [],
165
+ line = new Line(index, content, filePath, occurrences);
166
+
167
+ return line;
168
+ }
169
+ }
170
+
171
+ module.exports = Line;
172
+
173
+ function paddingFromPaddingLength(paddingLength) {
174
+ let padding = EMPTY_STRING;
175
+
176
+ for (let count = 0; count < paddingLength; count++) {
177
+ padding += SINGLE_SPACE;
178
+ }
179
+
180
+ return padding;
181
+ }
package/bin/main.js CHANGED
@@ -63,7 +63,7 @@ function main(command, argument, options) {
63
63
  }
64
64
 
65
65
  case FIND_COMMAND: {
66
- if (argument === null) {
66
+ if ((argument === null) && !dryRun) {
67
67
  console.log(NO_ARGUMENT_GIVEN_MESSAGE);
68
68
  } else {
69
69
  const string = argument; ///
package/bin/occurrence.js CHANGED
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ const { ZERO } = require("./constants");
4
+
3
5
  class Occurrence {
4
6
  constructor(start, end) {
5
7
  this.start = start;
@@ -14,20 +16,20 @@ class Occurrence {
14
16
  return this.end;
15
17
  }
16
18
 
17
- static fromResult(result) {
19
+ static fromResultAndOffset(result, offset) {
18
20
  const { index } = result,
19
- match = result[0], ///
21
+ match = result[ZERO],
20
22
  length = match.length,
21
- start = index, ///
23
+ start = index + offset,
22
24
  end = start + length,
23
25
  occurrence = new Occurrence(start, end);
24
26
 
25
27
  return occurrence;
26
28
  }
27
29
 
28
- static fromIndexAndString(index, string) {
30
+ static fromIndexStringAndOffset(index, string, offset) {
29
31
  const length = string.length,
30
- start = index, ///
32
+ start = index + offset,
31
33
  end = start + length,
32
34
  occurrence = new Occurrence(start, end);
33
35
 
@@ -112,12 +112,12 @@ function findInFile(filePath, callback, context) {
112
112
  }
113
113
 
114
114
  if (!filePathIgnored) {
115
- let { totalFiles } = context;
115
+ let { filesTotal } = context;
116
116
 
117
- totalFiles++;
117
+ filesTotal++;
118
118
 
119
119
  Object.assign(context, {
120
- totalFiles
120
+ filesTotal
121
121
  });
122
122
 
123
123
  const { dryRun } = context;
@@ -170,12 +170,12 @@ function findInDirectory(directoryPath, callback, context) {
170
170
  }
171
171
 
172
172
  if (!directoryPathIgnored) {
173
- let { totalDirectories } = context;
173
+ let { directoriesTotal } = context;
174
174
 
175
- totalDirectories++;
175
+ directoriesTotal++;
176
176
 
177
177
  Object.assign(context, {
178
- totalDirectories
178
+ directoriesTotal
179
179
  });
180
180
 
181
181
  const entryNames = readDirectory(directoryPath),
@@ -3,6 +3,14 @@
3
3
  const { ruleFromStringAnchoredAndDirectory } = require("../utilities/rule");
4
4
 
5
5
  function ruleOperation(proceed, abort, context) {
6
+ const { dryRun } = context;
7
+
8
+ if (dryRun) {
9
+ proceed();
10
+
11
+ return;
12
+ }
13
+
6
14
  const { string } = context,
7
15
  directory = false,
8
16
  anchored = false,
package/bin/rule/glob.js CHANGED
@@ -40,18 +40,23 @@ class GlobRule {
40
40
  return json;
41
41
  }
42
42
 
43
- find(string) {
44
- const occurrences = [];
43
+ find(line) {
44
+ const occurrences = [],
45
+ content = line.getContent();
45
46
 
46
- let result = string.match(this.regExp);
47
+ let offset = 0,
48
+ string = content, ///
49
+ result = string.match(this.regExp);
47
50
 
48
51
  while (result !== null) {
49
- const occurrence = Occurrence.fromResult(result),
52
+ const occurrence = Occurrence.fromResultAndOffset(result, offset),
50
53
  end = occurrence.getEnd(),
51
54
  start = end; ///
52
55
 
53
56
  string = string.substring(start); ///
54
57
 
58
+ offset += start;
59
+
55
60
  occurrences.push(occurrence);
56
61
 
57
62
  result = string.match(this.regExp);
package/bin/rule/regex.js CHANGED
@@ -36,18 +36,23 @@ class RegexRule {
36
36
  return json;
37
37
  }
38
38
 
39
- find(string) {
40
- const occurrences = [];
39
+ find(line) {
40
+ const occurrences = [],
41
+ content = line.getContent();
41
42
 
42
- let result = string.match(this.regExp);
43
+ let offset = 0,
44
+ string = content, ///
45
+ result = string.match(this.regExp);
43
46
 
44
47
  while (result !== null) {
45
- const occurrence = Occurrence.fromResult(result),
48
+ const occurrence = Occurrence.fromResultAndOffset(result, offset),
46
49
  end = occurrence.getEnd(),
47
50
  start = end; ///
48
51
 
49
52
  string = string.substring(start); ///
50
53
 
54
+ offset += start;
55
+
51
56
  occurrences.push(occurrence);
52
57
 
53
58
  result = string.match(this.regExp);
@@ -26,18 +26,23 @@ class StringRule {
26
26
  return json;
27
27
  }
28
28
 
29
- find(string) {
30
- const occurrences = [];
29
+ find(line) {
30
+ const occurrences = [],
31
+ content = line.getContent();
31
32
 
32
- let index = string.indexOf(this.string);
33
+ let offset = 0,
34
+ string = content, ///
35
+ index = string.indexOf(this.string);
33
36
 
34
37
  while (index !== -1) {
35
- const occurrence = Occurrence.fromIndexAndString(index, string),
38
+ const occurrence = Occurrence.fromIndexStringAndOffset(index, string, offset),
36
39
  end = occurrence.getEnd(),
37
40
  start = end; ///
38
41
 
39
42
  string = string.substring(start); ///
40
43
 
44
+ offset += start;
45
+
41
46
  occurrences.push(occurrence);
42
47
 
43
48
  index = string.match(this.regExp);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "find-cli",
3
3
  "author": "James Smith",
4
- "version": "1.4.3",
4
+ "version": "1.4.5",
5
5
  "license": "MIT, Anti-996",
6
6
  "homepage": "https://github.com/djalbat/find-cli",
7
7
  "description": "An alternative to grep.",