@ibgib/ts-gib 0.5.1 → 0.5.3

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.
@@ -0,0 +1,199 @@
1
+ import { readdir, open } from 'node:fs/promises';
2
+ import { statSync } from 'node:fs';
3
+ import * as pathUtils from 'path';
4
+
5
+ import { pretty } from '@ibgib/helper-gib';
6
+ import { getGlobalRespecGib } from '@ibgib/helper-gib/dist/respec-gib/respec-gib.mjs';
7
+
8
+ // #region settings
9
+ /**
10
+ * This is how I enable/disable verbose logging. Do with it what you will.
11
+ */
12
+ const logalot = false;
13
+
14
+ /** set this to the root of the respecs to look at */
15
+ const RESPEC_ROOT_DIR_RELATIVE_TO_BASE = './dist';
16
+
17
+ /** change this to suit your naming convention */
18
+ const RESPEC_FILE_REG_EXP = /^.+respec\.mjs$/;
19
+ // const RESPEC_FILE_REG_EXP = /^.*respec-gib.respec\.mjs$/;
20
+ // if (respecPath.includes('respec-gib.respec.mjs')) {
21
+
22
+ /**
23
+ * If on, will first load a file and see if there is an extra respecful
24
+ * `respecfully`/`ifWe` block. Use these if you want to focus on a single or
25
+ * subset of respecs.
26
+ *
27
+ * If there are no extra respecful blocks found in an entire file, that file
28
+ * will be skipped.
29
+ *
30
+ * Note: this only is a flag to search through respec files.
31
+ */
32
+ const LOOK_FOR_EXTRA_RESPEC = true;
33
+ /**
34
+ * The names of the functions that indicate that we want to focus on just those
35
+ * blocks.
36
+ *
37
+ * ATOW, for first run implementation here, I am implementing it such that it
38
+ * will filter out files that don't have these indicators. The respec files that
39
+ * do have these will execute fully, but the output will only include these
40
+ * particular blocks.
41
+ */
42
+ const EXTRA_RESPEC_FUNCTION_NAMES: string[] = ['respecfullyDear', 'ifWeMight'];
43
+
44
+ // #endregion settings
45
+
46
+ // #region 1. get respec paths
47
+
48
+ const basePath = process.cwd();
49
+ const srcPath = pathUtils.join(basePath, RESPEC_ROOT_DIR_RELATIVE_TO_BASE);
50
+
51
+ if (logalot) { console.log(`cwd: ${process.cwd()}`); }
52
+ if (logalot) { console.log(`basePath: ${basePath}`); }
53
+ if (logalot) { console.log(`srcPath: ${srcPath}`); }
54
+
55
+
56
+ const respecGib = getGlobalRespecGib();
57
+ const allRespecPaths = await getRespecFileFullPaths(srcPath, []);
58
+
59
+ if (logalot) { console.log(`allRespecPaths: ${allRespecPaths} (I: f5182a455375a8cf2aa6e1127a082423)`); }
60
+ let filteredRespecPaths: string[] | undefined = undefined;
61
+
62
+ if (LOOK_FOR_EXTRA_RESPEC) {
63
+ const hasExtraRespecPromises = allRespecPaths.map(async respecPath => {
64
+ const hasExtra = await respecFileHasExtraRespec(respecPath);
65
+ return [respecPath, hasExtra] as [string, boolean];
66
+ });
67
+ const resPathHasExtraTuples = await Promise.all(hasExtraRespecPromises);
68
+ filteredRespecPaths = resPathHasExtraTuples
69
+ .filter(([_respecPath, hasExtra]) => hasExtra)
70
+ .map(([respecPath, _hasExtra]) => respecPath);
71
+
72
+ // if there are no files that have extra respec then we do all files
73
+ if (filteredRespecPaths.length === 0) {
74
+ if (logalot) { console.log(`filteredRespecPaths is empty. doing allRespecPaths found (I: b98f54656899646025eecb4c028ab523)`); }
75
+ filteredRespecPaths = allRespecPaths.concat();
76
+ } else {
77
+ console.log(`filteredRespecPaths for extra respec: ${filteredRespecPaths} (I: b98f54656899646025eecb4c028ab523)`);
78
+ respecGib.extraRespecOnly = true;
79
+ }
80
+ }
81
+
82
+ // #endregion 1. get respec paths
83
+
84
+ respecGib.allRespecPaths = allRespecPaths;
85
+ respecGib.filteredRespecPaths = filteredRespecPaths;
86
+ const respecPaths = filteredRespecPaths ?? allRespecPaths;
87
+ respecGib.respecPaths = respecPaths;
88
+ if (logalot) { console.log(`respecPaths found:\n${respecPaths}`); }
89
+
90
+ // #region 2. execute paths' respective respecs
91
+
92
+ // for now, we'll do sequentially, but in the future we could conceivable farm
93
+ // these out to other node processes, or at least Promise.all
94
+
95
+ for (let i = 0; i < respecPaths.length; i++) {
96
+ const respecPath = respecPaths[i];
97
+ if (logalot) { console.log(respecPath); }
98
+ const esm = await import(respecPath);
99
+ if (logalot) { console.log(pretty(Object.keys(esm))); }
100
+ }
101
+
102
+ const skippedRespecPathCount = respecGib.allRespecPaths.length - respecGib.respecPaths.length;
103
+ if (skippedRespecPathCount > 0) {
104
+ console.log('');
105
+ console.error('\x1b[33m%s\x1b[0m', `${skippedRespecPathCount} respec files completely skipped.`); // yellow
106
+ }
107
+ if (respecGib.ifWeBlocksSkipped > 0) {
108
+ console.log('');
109
+ console.error('\x1b[33m%s\x1b[0m', `${respecGib.ifWeBlocksSkipped} ifWe blocks ran but skipped reporting`); // yellow
110
+ }
111
+
112
+ if (respecGib.errorMsgs.length === 0) {
113
+ console.log('');
114
+ console.error('\x1b[32m%s\x1b[0m', `💚💚 nothing but respec 💚💚`); // green
115
+ } else {
116
+ console.log('');
117
+ console.error('\x1b[31m%s\x1b[0m', `💔💔 DISrespec found 💔💔`); // red
118
+ for (const errorMsg of respecGib.errorMsgs) {
119
+ console.error('\x1b[31m%s\x1b[0m', errorMsg); // red
120
+ }
121
+ }
122
+
123
+ // #endregion 2. execute paths' respective respecs
124
+
125
+ // #region helper functions
126
+
127
+ /**
128
+ * builds a list of respec file paths, recursively traversing subdirectories
129
+ * starting from `dirPath`.
130
+ *
131
+ * @param dirPath a full path corresponding to a directory
132
+ * @param found respec paths already found (used in recursive calls)
133
+ * @returns list of all respec paths according to the respec regexp constant {@link RESPEC_FILE_REG_EXP}
134
+ */
135
+ async function getRespecFileFullPaths(dirPath: string, found: string[]): Promise<string[]> {
136
+ const lc = `[${getRespecFileFullPaths.name}][${dirPath}]`;
137
+ try {
138
+ if (logalot) { console.log(`${lc} starting... (I: 16026290523925f79ba1933847e2a623)`); }
139
+ found ??= [];
140
+ const children = await readdir(dirPath);
141
+ if (logalot) { for (let i = 0; i < children.length; i++) { console.log(children[i]); } }
142
+ const files: string[] = [];
143
+ const dirs: string[] = [];
144
+ children.forEach(name => {
145
+ const fullPath = pathUtils.join(dirPath, name);
146
+ const stat = statSync(fullPath);
147
+ if (stat.isDirectory()) {
148
+ // symbolic link could create a loop
149
+ if (!stat.isSymbolicLink()) { dirs.push(fullPath); }
150
+ } else if (!!name.match(RESPEC_FILE_REG_EXP)) {
151
+ files.push(fullPath);
152
+ }
153
+ });
154
+
155
+ found = found.concat(files);
156
+ for (let i = 0; i < dirs.length; i++) {
157
+ const subfound = await getRespecFileFullPaths(dirs[i], found);
158
+ found = found.concat(subfound);
159
+ }
160
+ return Array.from(new Set(found)); // unique
161
+ } catch (error) {
162
+ console.error(`${lc} ${error.message}`);
163
+ throw error;
164
+ } finally {
165
+ if (logalot) { console.log(`${lc} complete.`); }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Searches through the file (without importing it) for extra respecful
171
+ * functions.
172
+ *
173
+ * @param respecPath
174
+ * @returns true if extra respecful functions found in file
175
+ */
176
+ async function respecFileHasExtraRespec(respecPath: string): Promise<boolean> {
177
+ const lc = `[${respecFileHasExtraRespec.name}]`;
178
+ try {
179
+ if (logalot) { console.log(`${lc} starting... (I: 61f3221917ba77175efa305b14defc23)`); }
180
+ const file = await open(respecPath);
181
+ for await (const line of file.readLines()) {
182
+ const hasExtraRespecInLine =
183
+ EXTRA_RESPEC_FUNCTION_NAMES.some(fnName => {
184
+ if (line.includes(`${fnName}(`)) { return true; }
185
+ });
186
+ if (hasExtraRespecInLine) {
187
+ return true;
188
+ }
189
+ }
190
+ return false;
191
+ } catch (error) {
192
+ console.error(`${lc} ${error.message}`);
193
+ throw error;
194
+ } finally {
195
+ if (logalot) { console.log(`${lc} complete.`); }
196
+ }
197
+ }
198
+
199
+ // #endregion helper functions
package/tsconfig.json CHANGED
@@ -10,6 +10,8 @@
10
10
  "module": "ESNext", /* https://www.typescriptlang.org/docs/handbook/esm-node.html */
11
11
  },
12
12
  "exclude": [
13
+ "./dist",
14
+ "**/*.respec.mts",
13
15
  "**/*.spec.mts"
14
16
  ]
15
- }
17
+ }
@@ -5,6 +5,8 @@
5
5
  "module": "ESNext", /* https://www.typescriptlang.org/docs/handbook/esm-node.html */
6
6
  },
7
7
  "exclude": [
8
- // override inherited exclude of spec files
8
+ // override inherited exclude of respec files
9
+ "./dist",
10
+ "**/*.spec.mts"
9
11
  ]
10
- }
12
+ }
@@ -1,18 +0,0 @@
1
- {
2
- "srcDir": "dist",
3
- "srcFiles": [
4
- "**/*[!spec].mjs"
5
- ],
6
- "specDir": "dist",
7
- "specFiles": [
8
- "**/*.spec.mjs"
9
- ],
10
- "env": {
11
- "stopSpecOnExpectationFailure": false,
12
- "stopOnSpecFailure": false,
13
- "random": true
14
- },
15
- "browser": {
16
- "name": "headlessChrome"
17
- }
18
- }
package/jasmine.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "spec_dir": "dist",
3
- "spec_files": [
4
- "**/*.spec.mjs"
5
- ]
6
- }
@@ -1,59 +0,0 @@
1
- import { getIbAndGib, getIbGibAddr } from './helper.mjs';
2
- import { Ib, IbGib } from './types.mjs';
3
- import { ROOT, ROOT_ADDR } from './V1/constants.mjs';
4
-
5
-
6
- describe(`getIbGibAddr`, () => {
7
- // unsure if these would change when not in V1...(these tests are outside V1 atow)
8
-
9
- it(`should get the right addr for ROOT`, async () => {
10
- let ibGib = ROOT;
11
- let gotten = getIbGibAddr({ ibGib });
12
- expect(gotten).toBeTruthy();
13
- expect(gotten).toEqual(ROOT_ADDR);
14
- });
15
-
16
- it(`should get the right addr for primitives`, async () => {
17
- let ibs: Ib[] = ['7', 'foo', 'ibgib', 'wakka doodle'];
18
- for (let i = 0; i < ibs.length; i++) {
19
- const ib = ibs[i];
20
- let ibGib: IbGib = { ib, gib: 'gib' };
21
- let gotten = getIbGibAddr({ ibGib });
22
- expect(gotten).toBeTruthy();
23
- expect(gotten).toEqual(`${ib}^gib`);
24
- }
25
- });
26
-
27
- });
28
-
29
- describe(`getIbAndGib`, () => {
30
- // unsure if these would change when not in V1...(these tests are outside V1 atow)
31
-
32
- it(`should get the right ib & gib for ROOT, with ibGib param`, async () => {
33
- let ibGib = ROOT;
34
- let gotten = getIbAndGib({ ibGib });
35
- expect(gotten).toBeTruthy();
36
- expect(gotten.ib).toEqual('ib');
37
- expect(gotten.gib).toEqual('gib');
38
- });
39
-
40
- it(`should get the right ib & gib for ROOT_ADDR, with ibGibAddr param`, async () => {
41
- let gotten = getIbAndGib({ ibGibAddr: ROOT_ADDR });
42
- expect(gotten).toBeTruthy();
43
- expect(gotten.ib).toEqual('ib');
44
- expect(gotten.gib).toEqual('gib');
45
- });
46
-
47
- it(`should get the right ib & gib for primitives`, async () => {
48
- let ibs: Ib[] = ['7', 'foo', 'ibgib', 'wakka doodle'];
49
- for (let i = 0; i < ibs.length; i++) {
50
- const ib = ibs[i];
51
- let ibGib: IbGib = { ib, gib: 'gib' };
52
- let gotten = getIbAndGib({ ibGib });
53
- expect(gotten).toBeTruthy();
54
- expect(gotten.ib).toEqual(ib);
55
- expect(gotten.gib).toEqual('gib');
56
- }
57
- });
58
-
59
- });