Skip to content

Commit 2f0b17c

Browse files
authored
Fix build and prevent rm-rf accidents (#645)
1 parent cded580 commit 2f0b17c

File tree

10 files changed

+646
-161
lines changed

10 files changed

+646
-161
lines changed

.config/rollup.dist.config.mjs

Lines changed: 104 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ import commonjsPlugin from '@rollup/plugin-commonjs'
99
import jsonPlugin from '@rollup/plugin-json'
1010
import { nodeResolve } from '@rollup/plugin-node-resolve'
1111
import { glob as tinyGlob } from 'tinyglobby'
12+
import trash from 'trash'
1213

1314
import {
1415
isDirEmptySync,
1516
readJson,
16-
remove,
1717
writeJson,
1818
} from '@socketsecurity/registry/lib/fs'
1919
import { hasKeys, toSortedObject } from '@socketsecurity/registry/lib/objects'
@@ -41,8 +41,8 @@ const {
4141
NODE_MODULES,
4242
NODE_MODULES_GLOB_RECURSIVE,
4343
ROLLUP_EXTERNAL_SUFFIX,
44-
SHADOW_BIN,
45-
SHADOW_INJECT,
44+
SHADOW_NPM_BIN,
45+
SHADOW_NPM_INJECT,
4646
SLASH_NODE_MODULES_SLASH,
4747
SOCKET_CLI_BIN_NAME,
4848
SOCKET_CLI_BIN_NAME_ALIAS,
@@ -62,7 +62,7 @@ const {
6262
const BLESSED = 'blessed'
6363
const BLESSED_CONTRIB = 'blessed-contrib'
6464
const COANA_TECH_CLI = '@coana-tech/cli'
65-
const EXTERNAL = 'external'
65+
const LICENSE_MD = `LICENSE.md`
6666
const SENTRY_NODE = '@sentry/node'
6767
const SOCKET_DESCRIPTION = 'CLI for Socket.dev'
6868
const SOCKET_DESCRIPTION_WITH_SENTRY = `${SOCKET_DESCRIPTION}, includes Sentry error handling, otherwise identical to the regular \`${SOCKET_CLI_BIN_NAME}\` package`
@@ -85,6 +85,77 @@ async function copyBashCompletion() {
8585
await fs.copyFile(filepath, destPath)
8686
}
8787

88+
async function copyExternalPackages() {
89+
// Lazily access constants path properties.
90+
const { blessedContribPath, blessedPath, coanaPath, socketRegistryPath } =
91+
constants
92+
const nmPath = path.join(constants.rootPath, NODE_MODULES)
93+
const blessedContribNmPath = path.join(nmPath, BLESSED_CONTRIB)
94+
95+
// Copy package folders.
96+
await Promise.all([
97+
...EXTERNAL_PACKAGES
98+
// Skip copying 'blessed-contrib' over because we already
99+
// have it bundled as ./external/blessed-contrib.
100+
.filter(n => n !== BLESSED_CONTRIB)
101+
// Copy the other packages over to ./external/.
102+
.map(n =>
103+
copyPackage(n, {
104+
strict:
105+
// Skip adding 'use strict' directives to Coana and
106+
// Socket packages.
107+
n !== COANA_TECH_CLI && n !== SOCKET_SECURITY_REGISTRY,
108+
}),
109+
),
110+
// Copy 'blessed-contrib' license over to
111+
// ./external/blessed-contrib/LICENSE.md.
112+
await fs.cp(
113+
`${blessedContribNmPath}/${LICENSE_MD}`,
114+
`${blessedContribPath}/${LICENSE_MD}`,
115+
),
116+
])
117+
// Cleanup package files.
118+
await Promise.all(
119+
[
120+
[blessedPath, ['lib/**/*.js', 'usr/**/**', 'vendor/**/*.js', 'LICENSE*']],
121+
[blessedContribPath, ['lib/**/*.js', 'index.js', 'LICENSE*']],
122+
[coanaPath, ['**/*.mjs']],
123+
[
124+
socketRegistryPath,
125+
[
126+
'external/**/*.js',
127+
'lib/**/*.js',
128+
'index.js',
129+
'extensions.json',
130+
'manifest.json',
131+
'LICENSE*',
132+
],
133+
],
134+
].map(async ({ 0: thePath, 1: ignorePatterns }) => {
135+
await removeFiles(thePath, { exclude: ignorePatterns })
136+
await removeEmptyDirs(thePath)
137+
}),
138+
)
139+
// Rewire 'blessed' inside 'blessed-contrib'.
140+
await Promise.all(
141+
(
142+
await tinyGlob(['**/*.js'], {
143+
absolute: true,
144+
cwd: blessedContribPath,
145+
ignore: [NODE_MODULES_GLOB_RECURSIVE],
146+
})
147+
).map(async p => {
148+
const relPath = path.relative(path.dirname(p), blessedPath)
149+
const content = await fs.readFile(p, 'utf8')
150+
const modded = content.replace(
151+
/(?<=require\(["'])blessed(?=(?:\/[^"']+)?["']\))/g,
152+
() => relPath,
153+
)
154+
await fs.writeFile(p, modded, 'utf8')
155+
}),
156+
)
157+
}
158+
88159
async function copyPackage(pkgName, options) {
89160
const { strict = true } = { __proto__: null, ...options }
90161
// Lazily access constants path properties.
@@ -217,37 +288,32 @@ async function updatePackageLockFile() {
217288
}
218289

219290
async function removeEmptyDirs(thePath) {
220-
const dirPaths = (
221-
await tinyGlob(['**/'], {
222-
ignore: [NODE_MODULES_GLOB_RECURSIVE],
223-
absolute: true,
224-
cwd: thePath,
225-
onlyDirectories: true,
226-
})
291+
await trash(
292+
(
293+
await tinyGlob(['**/'], {
294+
ignore: [NODE_MODULES_GLOB_RECURSIVE],
295+
absolute: true,
296+
cwd: thePath,
297+
onlyDirectories: true,
298+
})
299+
)
300+
// Sort directory paths longest to shortest.
301+
.sort((a, b) => b.length - a.length)
302+
.filter(isDirEmptySync),
227303
)
228-
// Sort directory paths longest to shortest.
229-
.sort((a, b) => b.length - a.length)
230-
for (const dirPath of dirPaths) {
231-
if (isDirEmptySync(dirPath)) {
232-
// eslint-disable-next-line no-await-in-loop
233-
await remove(dirPath)
234-
}
235-
}
236304
}
237305

238306
async function removeFiles(thePath, options) {
239307
const { exclude } = { __proto__: null, ...options }
240308
const ignore = Array.isArray(exclude) ? exclude : exclude ? [exclude] : []
241-
return await Promise.all(
242-
(
243-
await tinyGlob(['**/*'], {
244-
absolute: true,
245-
onlyFiles: true,
246-
cwd: thePath,
247-
dot: true,
248-
ignore,
249-
})
250-
).map(p => remove(p)),
309+
return await trash(
310+
await tinyGlob(['**/*'], {
311+
absolute: true,
312+
onlyFiles: true,
313+
cwd: thePath,
314+
dot: true,
315+
ignore,
316+
}),
251317
)
252318
}
253319

@@ -289,9 +355,9 @@ function resetDependencies(deps) {
289355

290356
export default async () => {
291357
// Lazily access constants path properties.
292-
const { configPath, distPath, externalPath, rootPath, srcPath } = constants
358+
const { configPath, distPath, rootPath, srcPath } = constants
293359
const constantsSrcPath = path.join(srcPath, `constants.mts`)
294-
const externalSrcPath = path.join(srcPath, EXTERNAL)
360+
const externalSrcPath = path.join(srcPath, 'external')
295361
const nmPath = path.join(rootPath, NODE_MODULES)
296362
const shadowNpmBinSrcPath = path.join(srcPath, 'shadow/npm/bin.mts')
297363
const shadowNpmInjectSrcPath = path.join(srcPath, 'shadow/npm/inject.mts')
@@ -356,8 +422,8 @@ export default async () => {
356422
input: {
357423
cli: `${srcPath}/cli.mts`,
358424
[CONSTANTS]: `${srcPath}/constants.mts`,
359-
[SHADOW_BIN]: `${srcPath}/shadow/npm/bin.mts`,
360-
[SHADOW_INJECT]: `${srcPath}/shadow/npm/inject.mts`,
425+
[SHADOW_NPM_BIN]: `${srcPath}/shadow/npm/bin.mts`,
426+
[SHADOW_NPM_INJECT]: `${srcPath}/shadow/npm/inject.mts`,
361427
// Lazily access constants.ENV[INLINED_SOCKET_CLI_SENTRY_BUILD].
362428
...(constants.ENV[INLINED_SOCKET_CLI_SENTRY_BUILD]
363429
? {
@@ -379,9 +445,9 @@ export default async () => {
379445
case constantsSrcPath:
380446
return CONSTANTS
381447
case shadowNpmBinSrcPath:
382-
return SHADOW_BIN
448+
return SHADOW_NPM_BIN
383449
case shadowNpmInjectSrcPath:
384-
return SHADOW_INJECT
450+
return SHADOW_NPM_INJECT
385451
default:
386452
if (id.startsWith(utilsSrcPath)) {
387453
return UTILS
@@ -429,72 +495,10 @@ export default async () => {
429495
copyInitGradle(),
430496
copyBashCompletion(),
431497
updatePackageJson(),
432-
remove(path.join(distPath, `${VENDOR}.js.map`)),
433-
...EXTERNAL_PACKAGES.map(n =>
434-
copyPackage(n, {
435-
strict:
436-
n !== COANA_TECH_CLI && n !== SOCKET_SECURITY_REGISTRY,
437-
}),
438-
),
498+
// Remove dist/vendor.js.map file.
499+
trash([path.join(distPath, `${VENDOR}.js.map`)]),
500+
copyExternalPackages(),
439501
])
440-
441-
const blessedExternalPath = path.join(externalPath, BLESSED)
442-
const blessedContribExternalPath = path.join(
443-
externalPath,
444-
BLESSED_CONTRIB,
445-
)
446-
const filesEntries = [
447-
[
448-
blessedExternalPath,
449-
['lib/**/*.js', 'usr/**/**', 'vendor/**/*.js', 'LICENSE*'],
450-
],
451-
[
452-
blessedContribExternalPath,
453-
['lib/**/*.js', 'index.js', 'LICENSE*'],
454-
],
455-
[path.join(externalPath, COANA_TECH_CLI), ['**/*.mjs']],
456-
[
457-
path.join(externalPath, SOCKET_SECURITY_REGISTRY),
458-
[
459-
'external/**/*.js',
460-
'lib/**/*.js',
461-
'index.js',
462-
'extensions.json',
463-
'manifest.json',
464-
'LICENSE*',
465-
],
466-
],
467-
]
468-
469-
await Promise.all(
470-
filesEntries.map(async ({ 0: thePath, 1: ignorePatterns }) => {
471-
await removeFiles(thePath, { exclude: ignorePatterns })
472-
await removeEmptyDirs(thePath)
473-
}),
474-
)
475-
476-
// Rewire 'blessed' inside 'blessed-contrib'.
477-
await Promise.all(
478-
(
479-
await tinyGlob(['**/*.js'], {
480-
absolute: true,
481-
cwd: blessedContribExternalPath,
482-
ignore: [NODE_MODULES_GLOB_RECURSIVE],
483-
})
484-
).map(async p => {
485-
const relPath = path.relative(
486-
path.dirname(p),
487-
blessedExternalPath,
488-
)
489-
const content = await fs.readFile(p, 'utf8')
490-
const modded = content.replace(
491-
/(?<=require\(["'])blessed(?=(?:\/[^"']+)?["']\))/g,
492-
() => relPath,
493-
)
494-
await fs.writeFile(p, modded, 'utf8')
495-
}),
496-
)
497-
498502
// Update package-lock.json AFTER package.json.
499503
await updatePackageLockFile()
500504
},

bin/cli.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ spawn(
2828
...(constants.ENV.INLINED_SOCKET_CLI_SENTRY_BUILD
2929
? [
3030
'--require',
31-
// Lazily access constants.distInstrumentWithSentryPath.
32-
constants.distInstrumentWithSentryPath,
31+
// Lazily access constants.instrumentWithSentryPath.
32+
constants.instrumentWithSentryPath,
3333
]
3434
: []),
3535
// Lazily access constants.distCliPath.

0 commit comments

Comments
 (0)