Skip to content

Commit 5cf8291

Browse files
committed
Unify build script and sync to all repositories
- Create unified build.mjs script with flags (--source, --types, --watch, --if-needed, --quiet) - Add help flag support to build script - Fix remaining lint issues in all scripts - Update sync-scripts.mjs to include build script - Apply all unified scripts to socket-cli, socket-sdk-js, and socket-registry - Remove special case for package.json in affected-test-mapper
1 parent d52ab41 commit 5cf8291

File tree

8 files changed

+414
-72
lines changed

8 files changed

+414
-72
lines changed
File renamed without changes.
File renamed without changes.
File renamed without changes.

scripts/build.mjs

Lines changed: 236 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,267 @@
11
/**
2-
* @fileoverview Build script for socket-packageurl-js.
3-
* Orchestrates the complete build process:
4-
* - Cleans dist directory
5-
* - Compiles source with Rollup
6-
* - Generates TypeScript declarations
7-
*
8-
* Usage:
9-
* node scripts/build.mjs [--src-only|--types-only]
2+
* @fileoverview Unified build runner with flag-based configuration.
3+
* Orchestrates the complete build process with flexible options.
104
*/
115

6+
import { existsSync } from 'node:fs'
7+
import path from 'node:path'
8+
import { fileURLToPath } from 'node:url'
129
import { parseArgs } from 'node:util'
1310

14-
import { logger } from '@socketsecurity/registry/lib/logger'
11+
import colors from 'yoctocolors-cjs'
1512

16-
import { runSequence } from './utils/run-command.mjs'
13+
import { runCommand, runSequence } from './utils/run-command.mjs'
14+
15+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
16+
const rootPath = path.join(__dirname, '..')
17+
18+
// Simple clean logging without prefixes
19+
const log = {
20+
info: msg => console.log(msg),
21+
error: msg => console.error(`${colors.red('✗')} ${msg}`),
22+
success: msg => console.log(`${colors.green('✓')} ${msg}`),
23+
step: msg => console.log(`\n${msg}`),
24+
substep: msg => console.log(` ${msg}`),
25+
progress: msg => {
26+
// Write progress message without newline for in-place updates
27+
process.stdout.write(` ∴ ${msg}`)
28+
},
29+
done: msg => {
30+
// Clear current line and write success message
31+
// Carriage return + clear line
32+
process.stdout.write('\r\x1b[K')
33+
console.log(` ${colors.green('✓')} ${msg}`)
34+
},
35+
failed: msg => {
36+
// Clear current line and write failure message
37+
// Carriage return + clear line
38+
process.stdout.write('\r\x1b[K')
39+
console.log(` ${colors.red('✗')} ${msg}`)
40+
}
41+
}
42+
43+
/**
44+
* Build source code with Rollup.
45+
*/
46+
async function buildSource(options = {}) {
47+
const { quiet = false } = options
48+
49+
if (!quiet) {
50+
log.progress('Building source code')
51+
}
52+
53+
const exitCode = await runSequence([
54+
{ args: ['run', 'clean:dist'], command: 'pnpm' },
55+
{
56+
args: ['exec', 'rollup', '-c', '.config/rollup.dist.config.mjs'],
57+
command: 'pnpm',
58+
},
59+
])
60+
61+
if (exitCode !== 0) {
62+
if (!quiet) {
63+
log.failed('Source build failed')
64+
}
65+
return exitCode
66+
}
67+
68+
if (!quiet) {
69+
log.done('Source build complete')
70+
}
71+
72+
return 0
73+
}
74+
75+
/**
76+
* Build TypeScript declarations.
77+
*/
78+
async function buildTypes(options = {}) {
79+
const { quiet = false } = options
80+
81+
if (!quiet) {
82+
log.progress('Building TypeScript declarations')
83+
}
84+
85+
const exitCode = await runSequence([
86+
{ args: ['run', 'clean:dist:types'], command: 'pnpm' },
87+
{
88+
args: ['exec', 'tsgo', '--project', 'tsconfig.dts.json'],
89+
command: 'pnpm',
90+
},
91+
])
92+
93+
if (exitCode !== 0) {
94+
if (!quiet) {
95+
log.failed('Type declarations build failed')
96+
}
97+
return exitCode
98+
}
99+
100+
if (!quiet) {
101+
log.done('Type declarations built')
102+
}
103+
104+
return 0
105+
}
106+
107+
/**
108+
* Watch mode for development.
109+
*/
110+
async function watchBuild(options = {}) {
111+
const { quiet = false } = options
112+
113+
if (!quiet) {
114+
log.step('Starting watch mode')
115+
log.substep('Watching for file changes...')
116+
}
117+
118+
const exitCode = await runCommand(
119+
'pnpm',
120+
['exec', 'rollup', '-c', '.config/rollup.dist.config.mjs', '--watch'],
121+
{
122+
stdio: 'inherit'
123+
}
124+
)
125+
126+
return exitCode
127+
}
128+
129+
/**
130+
* Check if build is needed.
131+
*/
132+
function isBuildNeeded() {
133+
const distPath = path.join(rootPath, 'dist', 'index.js')
134+
const distTypesPath = path.join(rootPath, 'dist', 'types', 'index.d.ts')
135+
136+
return !existsSync(distPath) || !existsSync(distTypesPath)
137+
}
17138

18139
async function main() {
19140
try {
141+
// Parse arguments
20142
const { values } = parseArgs({
21143
options: {
22-
'src-only': { type: 'boolean', default: false },
23-
'types-only': { type: 'boolean', default: false },
144+
help: {
145+
type: 'boolean',
146+
default: false,
147+
},
148+
source: {
149+
type: 'boolean',
150+
default: false,
151+
},
152+
types: {
153+
type: 'boolean',
154+
default: false,
155+
},
156+
watch: {
157+
type: 'boolean',
158+
default: false,
159+
},
160+
'if-needed': {
161+
type: 'boolean',
162+
default: false,
163+
},
164+
quiet: {
165+
type: 'boolean',
166+
default: false,
167+
},
24168
},
169+
allowPositionals: false,
25170
strict: false,
26171
})
27172

28-
const srcOnly = values['src-only']
29-
const typesOnly = values['types-only']
30-
31-
if (typesOnly) {
32-
logger.log('Building TypeScript declarations only...')
33-
const exitCode = await runSequence([
34-
{ args: ['run', 'clean:dist:types'], command: 'pnpm' },
35-
{
36-
args: ['exec', 'tsgo', '--project', 'tsconfig.dts.json'],
37-
command: 'pnpm',
38-
},
39-
])
40-
process.exitCode = exitCode
173+
// Show help if requested
174+
if (values.help) {
175+
console.log('Socket PackageURL Build Runner')
176+
console.log('\nUsage: pnpm build [options]')
177+
console.log('\nOptions:')
178+
console.log(' --help Show this help message')
179+
console.log(' --source Build source code only')
180+
console.log(' --types Build TypeScript declarations only')
181+
console.log(' --watch Watch mode for development')
182+
console.log(' --if-needed Only build if dist files are missing')
183+
console.log(' --quiet Suppress progress messages')
184+
console.log('\nExamples:')
185+
console.log(' pnpm build # Full build (source + types)')
186+
console.log(' pnpm build --source # Build source only')
187+
console.log(' pnpm build --types # Build types only')
188+
console.log(' pnpm build --watch # Watch mode')
189+
console.log(' pnpm build --if-needed # Build only if needed')
190+
process.exitCode = 0
41191
return
42192
}
43193

44-
if (srcOnly) {
45-
logger.log('Building source only...')
46-
const exitCode = await runSequence([
47-
{ args: ['run', 'clean:dist'], command: 'pnpm' },
48-
{
49-
args: ['exec', 'rollup', '-c', '.config/rollup.dist.config.mjs'],
50-
command: 'pnpm',
51-
},
52-
])
53-
process.exitCode = exitCode
194+
// Check if build is needed
195+
if (values['if-needed'] && !isBuildNeeded()) {
196+
if (!values.quiet) {
197+
log.info('Build artifacts exist, skipping build')
198+
}
199+
process.exitCode = 0
54200
return
55201
}
56202

57-
// Build both src and types
58-
logger.log('Building package (source + types)...')
203+
if (!values.quiet) {
204+
console.log('═══════════════════════════════════════════════════════')
205+
console.log(' Socket PackageURL Build Runner')
206+
console.log('═══════════════════════════════════════════════════════')
207+
}
59208

60-
// Build src
61-
const srcExitCode = await runSequence([
62-
{ args: ['run', 'clean:dist'], command: 'pnpm' },
63-
{
64-
args: ['exec', 'rollup', '-c', '.config/rollup.dist.config.mjs'],
65-
command: 'pnpm',
66-
},
67-
])
209+
let exitCode = 0
68210

69-
if (srcExitCode !== 0) {
70-
process.exitCode = srcExitCode
71-
return
211+
// Handle watch mode
212+
if (values.watch) {
213+
exitCode = await watchBuild({ quiet: values.quiet })
214+
}
215+
// Build types only
216+
else if (values.types && !values.source) {
217+
if (!values.quiet) {
218+
log.step('Building TypeScript declarations only')
219+
}
220+
exitCode = await buildTypes({ quiet: values.quiet })
72221
}
222+
// Build source only
223+
else if (values.source && !values.types) {
224+
if (!values.quiet) {
225+
log.step('Building source only')
226+
}
227+
exitCode = await buildSource({ quiet: values.quiet })
228+
}
229+
// Build everything (default)
230+
else {
231+
if (!values.quiet) {
232+
log.step('Building package (source + types)')
233+
}
73234

74-
// Build types
75-
const typesExitCode = await runSequence([
76-
{ args: ['run', 'clean:dist:types'], command: 'pnpm' },
77-
{
78-
args: ['exec', 'tsgo', '--project', 'tsconfig.dts.json'],
79-
command: 'pnpm',
80-
},
81-
])
235+
// Build source first
236+
exitCode = await buildSource({ quiet: values.quiet })
237+
if (exitCode !== 0) {
238+
if (!values.quiet) {
239+
log.error('Build failed')
240+
}
241+
process.exitCode = exitCode
242+
return
243+
}
82244

83-
process.exitCode = typesExitCode
245+
// Then build types
246+
exitCode = await buildTypes({ quiet: values.quiet })
247+
}
248+
249+
if (exitCode !== 0) {
250+
if (!values.quiet) {
251+
log.error('Build failed')
252+
}
253+
process.exitCode = exitCode
254+
} else {
255+
if (!values.quiet) {
256+
console.log('\n═══════════════════════════════════════════════════════')
257+
log.success('Build completed successfully!')
258+
console.log('═══════════════════════════════════════════════════════')
259+
}
260+
}
84261
} catch (error) {
85-
logger.error('Build failed:', error.message)
262+
log.error(`Build runner failed: ${error.message}`)
86263
process.exitCode = 1
87264
}
88265
}
89266

90-
main().catch(console.error)
267+
main().catch(console.error)

scripts/lint.mjs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,14 @@
33
* Provides smart linting that can target affected files or lint everything.
44
*/
55

6-
import { promises as fs } from 'node:fs'
76
import path from 'node:path'
8-
import { fileURLToPath } from 'node:url'
97
import { parseArgs } from 'node:util'
108

119
import colors from 'yoctocolors-cjs'
1210

13-
import WIN32 from '@socketsecurity/registry/lib/constants/WIN32'
14-
import { logger } from '@socketsecurity/registry/lib/logger'
15-
1611
import { getChangedFiles, getStagedFiles } from './utils/git.mjs'
1712
import { runCommandQuiet } from './utils/run-command.mjs'
1813

19-
const __dirname = path.dirname(fileURLToPath(import.meta.url))
20-
const rootPath = path.join(__dirname, '..')
21-
2214
// Simple clean logging without prefixes
2315
const log = {
2416
info: msg => console.log(msg),
@@ -212,7 +204,7 @@ async function runLintOnAll(options = {}) {
212204
* Get files to lint based on options.
213205
*/
214206
async function getFilesToLint(options) {
215-
const { all, staged, affected, preCommit } = options
207+
const { affected, all, preCommit, staged } = options
216208

217209
// If --all, return early
218210
if (all) {
@@ -239,7 +231,7 @@ async function getFilesToLint(options) {
239231
}
240232

241233
// Check if we should run all based on changed files
242-
const { runAll, reason } = shouldRunAllLinters(changedFiles)
234+
const { reason, runAll } = shouldRunAllLinters(changedFiles)
243235
if (runAll) {
244236
return { files: 'all', reason }
245237
}
@@ -309,7 +301,8 @@ async function main() {
309301
console.log(' pnpm lint --affected # Lint changed files')
310302
console.log(' pnpm lint --staged --fix # Fix issues in staged files')
311303
console.log(' pnpm lint src/index.ts # Lint specific file(s)')
312-
process.exit(0)
304+
process.exitCode = 0
305+
return
313306
}
314307

315308
if (!values.quiet) {

0 commit comments

Comments
 (0)