fg-devkit 1.22.0 → 1.24.0

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.
Files changed (69) hide show
  1. package/README.md +30 -7
  2. package/configs/dependency-policy.vue-workspace.json +28 -28
  3. package/package.json +12 -85
  4. package/scaffold/vue/package.json +13 -13
  5. package/scripts/audit-override-commit.mjs +167 -24
  6. package/scripts/bump-node-toolchain.mjs +8 -31
  7. package/scripts/bump-pnpm-toolchain.mjs +8 -29
  8. package/scripts/check-dependency-policy.mjs +10 -35
  9. package/scripts/fg-devkit.mjs +290 -337
  10. package/scripts/fleet-bump-fg-devkit.mjs +4 -5
  11. package/scripts/fleet-git-commit-push-scoped.mjs +6 -26
  12. package/scripts/fleet-git-discard-scoped.mjs +5 -25
  13. package/scripts/fleet-git-pull-scoped.mjs +5 -25
  14. package/scripts/fleet-vulns.mjs +4 -9
  15. package/scripts/generate-release-notes.mjs +1 -1
  16. package/scripts/{audit-fix-plan.mjs → lib/audit-fix-plan.mjs} +77 -4
  17. package/scripts/{audit-fix-plan.test.mjs → lib/audit-fix-plan.test.mjs} +50 -2
  18. package/scripts/lib/common.mjs +95 -0
  19. package/scripts/{dependency-policy-toolchain.mjs → lib/dependency-policy-toolchain.mjs} +3 -35
  20. package/scripts/{git-commit-push-fleet-common.mjs → lib/git-commit-push-fleet-common.mjs} +1 -1
  21. package/scripts/{git-discard-fleet-common.mjs → lib/git-discard-fleet-common.mjs} +1 -1
  22. package/scripts/{git-pull-fleet-common.mjs → lib/git-pull-fleet-common.mjs} +1 -1
  23. package/scripts/{override-changes.mjs → lib/override-changes.mjs} +20 -0
  24. package/scripts/{piwik-dimensions.test.mjs → lib/piwik-dimensions.test.mjs} +0 -5
  25. package/scripts/{release-notes-common.mjs → lib/release-notes-common.mjs} +5 -7
  26. package/scripts/{resolve-dependency-policy-path.mjs → lib/resolve-dependency-policy-path.mjs} +4 -3
  27. package/scripts/piwik.mjs +6 -6
  28. package/scripts/poeditor-download.mjs +1 -1
  29. package/scripts/poeditor-upload.mjs +1 -1
  30. package/scripts/policy-outdated.mjs +3 -8
  31. package/scripts/policy-upgrade-commit.mjs +5 -26
  32. package/scripts/policy-upgrade.mjs +6 -30
  33. package/scripts/policy-vulns.mjs +3 -8
  34. package/scripts/prune-overrides.mjs +5 -16
  35. package/scripts/prune-release-age-exclude.mjs +1 -1
  36. package/scripts/refresh-dependency-policy-from-repos.mjs +5 -7
  37. package/scripts/release.sh +2 -1
  38. package/scripts/scaffold-vue.mjs +1 -3
  39. package/scripts/setup-ai-rules.mjs +135 -0
  40. package/scripts/sync-consumer-lefthook.mjs +7 -24
  41. package/scripts/sync-dependency-check-suppressions-commit.mjs +7 -46
  42. package/scripts/sync-dependency-policy-commit.mjs +6 -38
  43. package/scripts/sync-dependency-policy.mjs +9 -35
  44. package/scripts/sync-node-toolchain.mjs +5 -8
  45. package/scripts/sync-pnpm-toolchain.mjs +5 -8
  46. package/scripts/sync-scaffold-vue-deps.mjs +6 -7
  47. package/scripts/sync-tooling-configs.mjs +8 -23
  48. package/scripts/sync-vite-plugin-vue-inspector.mjs +7 -39
  49. package/scripts/verify-release-notes.mjs +1 -1
  50. package/.cursor/rules/core-coding-standards.mdc +0 -291
  51. package/scaffold/vue/.gitignore +0 -13
  52. package/scripts/cz/.cz-config.cjs +0 -29
  53. package/scripts/fleet-git-commit-push.mjs +0 -75
  54. package/scripts/fleet-git-discard.mjs +0 -66
  55. package/scripts/fleet-git-pull.mjs +0 -65
  56. package/scripts/sync-core-coding-standards.mjs +0 -77
  57. package/scripts/sync-peers-from-dev.mjs +0 -31
  58. package/scripts/vuln-commit.mjs +0 -142
  59. /package/configs/{fallowrc.sync-stub.json → fallowrc.json} +0 -0
  60. /package/scripts/{dependency-policy-pins.mjs → lib/dependency-policy-pins.mjs} +0 -0
  61. /package/scripts/{fleet-project-repos.mjs → lib/fleet-project-repos.mjs} +0 -0
  62. /package/scripts/{fleet-repo-picker.mjs → lib/fleet-repo-picker.mjs} +0 -0
  63. /package/scripts/{fleet-vue-repos.mjs → lib/fleet-vue-repos.mjs} +0 -0
  64. /package/scripts/{git-fleet-common.mjs → lib/git-fleet-common.mjs} +0 -0
  65. /package/scripts/{node-toolchain-sync.mjs → lib/node-toolchain-sync.mjs} +0 -0
  66. /package/scripts/{piwik-common.mjs → lib/piwik-common.mjs} +0 -0
  67. /package/scripts/{piwik-dimensions.mjs → lib/piwik-dimensions.mjs} +0 -0
  68. /package/scripts/{pnpm-toolchain-sync.mjs → lib/pnpm-toolchain-sync.mjs} +0 -0
  69. /package/scripts/{poeditor-common.mjs → lib/poeditor-common.mjs} +0 -0
@@ -13,16 +13,16 @@
13
13
 
14
14
  import fs from 'node:fs'
15
15
  import path from 'node:path'
16
- import { fileURLToPath } from 'node:url'
17
16
  import { spawnSync } from 'node:child_process'
18
17
  import { parseArgs } from 'node:util'
19
- import { filterSuppressions, normalizeAdvisories, parseAuditJson, parseSuppressions } from './audit-fix-plan.mjs'
18
+ import { filterSuppressions, normalizeAdvisories, parseAuditJson, parseSuppressions } from './lib/audit-fix-plan.mjs'
19
+ import { fileDiffersFromHead, findFgDevkitPackageRoot, runGit } from './lib/common.mjs'
20
20
 
21
21
  const TAG = '[sync-dependency-check-suppressions]'
22
22
  const FILE_NAME = 'dependency-check-suppressions.xml'
23
23
  const COMMIT_MESSAGE = 'chore(repo): sync dependency-check suppressions'
24
24
  const projectRoot = process.cwd()
25
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
25
+ const GIT = { cwd: projectRoot, tag: TAG }
26
26
 
27
27
  const { values: args } = parseArgs({
28
28
  options: {
@@ -42,45 +42,6 @@ pnpm audit reports in this repo, and auto-commits it.
42
42
  process.exit(0)
43
43
  }
44
44
 
45
- function findFgDevkitPackageRoot() {
46
- const candidates = [
47
- path.resolve(scriptDir, '..'),
48
- path.join(projectRoot, 'node_modules', 'fg-devkit'),
49
- path.join(projectRoot, 'node_modules', 'fds-vue-core', 'node_modules', 'fg-devkit'),
50
- ]
51
- for (const candidate of candidates) {
52
- if (fs.existsSync(path.join(candidate, 'package.json'))) {
53
- return candidate
54
- }
55
- }
56
- return null
57
- }
58
-
59
- function runGit(gitArgs, options = {}) {
60
- const result = spawnSync('git', gitArgs, {
61
- stdio: options.capture ? 'pipe' : 'inherit',
62
- encoding: options.capture ? 'utf8' : undefined,
63
- cwd: projectRoot,
64
- env: process.env,
65
- })
66
- if (result.error) {
67
- console.error(TAG, result.error.message)
68
- return { status: 1, stdout: '' }
69
- }
70
- return { status: result.status ?? 1, stdout: result.stdout ?? '' }
71
- }
72
-
73
- function fileDiffersFromHead(filePath) {
74
- const absolutePath = path.join(projectRoot, filePath)
75
- if (!fs.existsSync(absolutePath)) return false
76
-
77
- const tracked = runGit(['ls-files', '--error-unmatch', '--', filePath], { capture: true })
78
- if (tracked.status !== 0) return true
79
-
80
- const diff = runGit(['diff', '--quiet', 'HEAD', '--', filePath], { capture: true })
81
- return diff.status !== 0
82
- }
83
-
84
45
  /** GHSA ids `pnpm audit` reports in this repo. Exits on audit failure so nothing is written blindly. */
85
46
  function reportedGhsas() {
86
47
  const result = spawnSync('pnpm', ['audit', '--json'], {
@@ -97,7 +58,7 @@ function reportedGhsas() {
97
58
  return new Set(normalizeAdvisories(parseAuditJson(result.stdout)).map((advisory) => advisory.ghsa))
98
59
  }
99
60
 
100
- const fgRoot = findFgDevkitPackageRoot()
61
+ const fgRoot = findFgDevkitPackageRoot(projectRoot)
101
62
  if (!fgRoot) {
102
63
  console.error(`${TAG} Could not find fg-devkit (install fg-devkit or a package that bundles it, e.g. fds-vue-core).`)
103
64
  process.exit(1)
@@ -137,13 +98,13 @@ if (!args.all) {
137
98
  fs.writeFileSync(targetPath, content)
138
99
  console.log(`${TAG} Updated ${FILE_NAME}.`)
139
100
 
140
- if (!fileDiffersFromHead(FILE_NAME)) {
101
+ if (!fileDiffersFromHead(FILE_NAME, GIT)) {
141
102
  console.log(`${TAG} No changes to commit.`)
142
103
  process.exit(0)
143
104
  }
144
105
 
145
- const stage = runGit(['add', '--', FILE_NAME])
106
+ const stage = runGit(['add', '--', FILE_NAME], GIT)
146
107
  if (stage.status !== 0) process.exit(stage.status)
147
108
 
148
109
  console.log(`${TAG} Auto-committing: ${COMMIT_MESSAGE}`)
149
- process.exit(runGit(['commit', '-m', COMMIT_MESSAGE]).status)
110
+ process.exit(runGit(['commit', '-m', COMMIT_MESSAGE], GIT).status)
@@ -6,12 +6,13 @@
6
6
  * pnpm exec fg-devkit sync-deps-commit [policy-file]
7
7
  */
8
8
 
9
- import fs from 'node:fs'
10
9
  import path from 'node:path'
11
10
  import { fileURLToPath } from 'node:url'
12
11
  import { spawnSync } from 'node:child_process'
12
+ import { fileDiffersFromHead, runGit, stageExistingFiles } from './lib/common.mjs'
13
13
 
14
14
  const cwd = process.cwd()
15
+ const GIT = { cwd, tag: '[sync-deps-commit]' }
15
16
  const scriptDir = path.dirname(fileURLToPath(import.meta.url))
16
17
  const syncScriptPath = path.join(scriptDir, 'sync-dependency-policy.mjs')
17
18
  const commitMessage = 'chore(repo): sync dependency policy'
@@ -44,22 +45,8 @@ function runPnpm(args) {
44
45
  return result.status ?? 1
45
46
  }
46
47
 
47
- function runGit(args, options = {}) {
48
- const result = spawnSync('git', args, {
49
- stdio: options.capture ? 'pipe' : 'inherit',
50
- encoding: options.capture ? 'utf8' : undefined,
51
- cwd,
52
- env: process.env,
53
- })
54
- if (result.error) {
55
- console.error('[sync-deps-commit]', result.error.message)
56
- return { status: 1, stdout: '' }
57
- }
58
- return { status: result.status ?? 1, stdout: result.stdout ?? '' }
59
- }
60
-
61
48
  function listTrackedFiles() {
62
- const result = runGit(['ls-files', '-z'], { capture: true })
49
+ const result = runGit(['ls-files', '-z'], { ...GIT, capture: true })
63
50
  if (result.status !== 0) return []
64
51
  return result.stdout.split('\0').filter(Boolean)
65
52
  }
@@ -84,25 +71,6 @@ function isSyncRelatedPath(filePath) {
84
71
  return base.endsWith('.sh')
85
72
  }
86
73
 
87
- function fileDiffersFromHead(filePath) {
88
- const absolutePath = path.join(cwd, filePath)
89
- if (!fs.existsSync(absolutePath)) return false
90
-
91
- const tracked = runGit(['ls-files', '--error-unmatch', '--', filePath], { capture: true })
92
- if (tracked.status !== 0) {
93
- return true
94
- }
95
-
96
- const diff = runGit(['diff', '--quiet', 'HEAD', '--', filePath], { capture: true })
97
- return diff.status !== 0
98
- }
99
-
100
- function stageExistingFiles(files) {
101
- const existingFiles = files.filter((filePath) => fs.existsSync(path.join(cwd, filePath)))
102
- if (existingFiles.length === 0) return 0
103
- return runGit(['add', '--', ...existingFiles]).status
104
- }
105
-
106
74
  function main() {
107
75
  const syncResult = runSync(process.argv.slice(2))
108
76
  if (syncResult.status !== 0) {
@@ -135,20 +103,20 @@ function main() {
135
103
  }
136
104
  }
137
105
 
138
- const filesToStage = [...candidateFiles].filter((filePath) => fileDiffersFromHead(filePath))
106
+ const filesToStage = [...candidateFiles].filter((filePath) => fileDiffersFromHead(filePath, GIT))
139
107
  if (filesToStage.length === 0) {
140
108
  console.log('[sync-deps-commit] No sync-related changes to commit.')
141
109
  process.exit(0)
142
110
  }
143
111
 
144
- const stageExitCode = stageExistingFiles(filesToStage)
112
+ const stageExitCode = stageExistingFiles(filesToStage, GIT)
145
113
  if (stageExitCode !== 0) {
146
114
  process.exit(stageExitCode)
147
115
  }
148
116
 
149
117
  console.log(`[sync-deps-commit] Staged ${filesToStage.length} file(s)`)
150
118
  console.log(`[sync-deps-commit] Auto-committing: ${commitMessage}`)
151
- process.exit(runGit(['commit', '-m', commitMessage]).status)
119
+ process.exit(runGit(['commit', '-m', commitMessage], GIT).status)
152
120
  }
153
121
 
154
122
  main()
@@ -13,24 +13,23 @@
13
13
 
14
14
  import fs from 'node:fs'
15
15
  import path from 'node:path'
16
- import { fileURLToPath } from 'node:url'
17
16
 
18
- import { collectPinViolations } from './dependency-policy-pins.mjs'
17
+ import { collectPinViolations } from './lib/dependency-policy-pins.mjs'
19
18
  import {
20
19
  collectNodeToolchainPolicyViolations,
21
20
  collectToolchainPolicyViolations,
22
21
  resolveExpectedPackageManager,
23
- } from './dependency-policy-toolchain.mjs'
24
- import { syncNodeToolchainInRepo } from './node-toolchain-sync.mjs'
25
- import { syncPnpmToolchainInRepo } from './pnpm-toolchain-sync.mjs'
26
- import { resolveDependencyPolicyPath } from './resolve-dependency-policy-path.mjs'
22
+ } from './lib/dependency-policy-toolchain.mjs'
23
+ import { syncNodeToolchainInRepo } from './lib/node-toolchain-sync.mjs'
24
+ import { syncPnpmToolchainInRepo } from './lib/pnpm-toolchain-sync.mjs'
25
+ import { resolveDependencyPolicyPath } from './lib/resolve-dependency-policy-path.mjs'
26
+ import { getRelevantPolicyOverrides } from './lib/override-changes.mjs'
27
+ import { fgDevkitRoot } from './lib/common.mjs'
27
28
 
28
29
  const cwd = process.cwd()
29
30
  const pkgPath = path.resolve(cwd, 'package.json')
30
31
  const lockfilePath = path.resolve(cwd, 'pnpm-lock.yaml')
31
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
32
- const fgDevkitRoot = path.resolve(scriptDir, '..')
33
- const policyPath = resolveDependencyPolicyPath(scriptDir, cwd, process.argv)
32
+ const policyPath = resolveDependencyPolicyPath(cwd, process.argv)
34
33
 
35
34
  if (!fs.existsSync(pkgPath)) {
36
35
  console.error('[sync-deps] Could not find package.json in current working directory')
@@ -67,31 +66,6 @@ if (policyErrors.length > 0) {
67
66
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'))
68
67
  const changes = []
69
68
 
70
- function getOverridePackageName(overrideKey) {
71
- const match = overrideKey.match(/^(@[^/]+\/[^@]+|[^@]+)@/)
72
- return match ? match[1] : overrideKey
73
- }
74
-
75
- function getRelevantPolicyOverrides(policyOverrides) {
76
- const entries = Object.entries(policyOverrides ?? {})
77
- if (entries.length === 0) {
78
- return {}
79
- }
80
- if (!fs.existsSync(lockfilePath)) {
81
- return Object.fromEntries(entries)
82
- }
83
- const lockfile = fs.readFileSync(lockfilePath, 'utf8')
84
- const relevant = {}
85
- for (const [name, version] of entries) {
86
- const pkgName = getOverridePackageName(name)
87
- // Conservative: only apply overrides for packages present in lockfile.
88
- if (lockfile.includes(`${pkgName}@`) || lockfile.includes(`/${pkgName}/`)) {
89
- relevant[name] = version
90
- }
91
- }
92
- return relevant
93
- }
94
-
95
69
  // Bump versions for managed dependencies / devDependencies where the key already exists.
96
70
  for (const [section, dependencies] of Object.entries(policy.managedDependencies ?? {})) {
97
71
  pkg[section] ||= {}
@@ -136,7 +110,7 @@ for (const [name, version] of Object.entries(policy.managedAnywhere ?? {})) {
136
110
  }
137
111
 
138
112
  // Apply policy-defined override versions when present in the policy.
139
- const relevantOverrides = getRelevantPolicyOverrides(policy.overrides ?? {})
113
+ const relevantOverrides = getRelevantPolicyOverrides(policy.overrides, lockfilePath)
140
114
  for (const [name, version] of Object.entries(relevantOverrides)) {
141
115
  if (pkg.pnpm?.overrides?.[name] === version) {
142
116
  continue
@@ -13,22 +13,19 @@
13
13
  */
14
14
 
15
15
  import fs from 'node:fs'
16
- import path from 'node:path'
17
- import { fileURLToPath } from 'node:url'
18
16
 
19
17
  import {
20
18
  collectNodeToolchainPolicyViolations,
21
19
  resolveExpectedNodePolicy,
22
- } from './dependency-policy-toolchain.mjs'
23
- import { syncNodeToolchainInRepo } from './node-toolchain-sync.mjs'
24
- import { resolveDependencyPolicyPath } from './resolve-dependency-policy-path.mjs'
20
+ } from './lib/dependency-policy-toolchain.mjs'
21
+ import { syncNodeToolchainInRepo } from './lib/node-toolchain-sync.mjs'
22
+ import { resolveDependencyPolicyPath } from './lib/resolve-dependency-policy-path.mjs'
23
+ import { fgDevkitRoot } from './lib/common.mjs'
25
24
 
26
25
  const cwd = process.cwd()
27
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
28
- const fgDevkitRoot = path.resolve(scriptDir, '..')
29
26
  const cliArgs = process.argv.slice(2).filter((a) => a !== '--dry-run')
30
27
  const dryRun = process.argv.includes('--dry-run')
31
- const policyPath = resolveDependencyPolicyPath(scriptDir, cwd, ['node', 'sync-node-toolchain.mjs', ...cliArgs])
28
+ const policyPath = resolveDependencyPolicyPath(cwd, ['node', 'sync-node-toolchain.mjs', ...cliArgs])
32
29
 
33
30
  if (!fs.existsSync(policyPath)) {
34
31
  console.error(`[sync-node-toolchain] Could not find dependency policy: ${policyPath}`)
@@ -7,22 +7,19 @@
7
7
  */
8
8
 
9
9
  import fs from 'node:fs'
10
- import path from 'node:path'
11
- import { fileURLToPath } from 'node:url'
12
10
 
13
11
  import {
14
12
  collectToolchainPolicyViolations,
15
13
  resolveExpectedPackageManager,
16
- } from './dependency-policy-toolchain.mjs'
17
- import { syncPnpmToolchainInRepo } from './pnpm-toolchain-sync.mjs'
18
- import { resolveDependencyPolicyPath } from './resolve-dependency-policy-path.mjs'
14
+ } from './lib/dependency-policy-toolchain.mjs'
15
+ import { syncPnpmToolchainInRepo } from './lib/pnpm-toolchain-sync.mjs'
16
+ import { resolveDependencyPolicyPath } from './lib/resolve-dependency-policy-path.mjs'
17
+ import { fgDevkitRoot } from './lib/common.mjs'
19
18
 
20
19
  const cwd = process.cwd()
21
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
22
- const fgDevkitRoot = path.resolve(scriptDir, '..')
23
20
  const cliArgs = process.argv.slice(2).filter((a) => a !== '--dry-run')
24
21
  const dryRun = process.argv.includes('--dry-run')
25
- const policyPath = resolveDependencyPolicyPath(scriptDir, cwd, ['node', 'sync-pnpm-toolchain.mjs', ...cliArgs])
22
+ const policyPath = resolveDependencyPolicyPath(cwd, ['node', 'sync-pnpm-toolchain.mjs', ...cliArgs])
26
23
 
27
24
  if (!fs.existsSync(policyPath)) {
28
25
  console.error(`[sync-pnpm-toolchain] Could not find dependency policy: ${policyPath}`)
@@ -12,15 +12,16 @@ import fs from 'node:fs'
12
12
  import path from 'node:path'
13
13
  import { fileURLToPath } from 'node:url'
14
14
 
15
- import { resolveDependencyPolicyPath } from './resolve-dependency-policy-path.mjs'
15
+ import { resolveDependencyPolicyPath } from './lib/resolve-dependency-policy-path.mjs'
16
16
  import {
17
17
  extractPnpmVersion,
18
18
  resolveExpectedNodePolicy,
19
19
  resolveExpectedPackageManager,
20
20
  syncPolicyToolchainFromFgDevkit,
21
- } from './dependency-policy-toolchain.mjs'
22
- import { syncDockerfileNodeImages } from './node-toolchain-sync.mjs'
23
- import { syncDockerfilePnpmVersion } from './pnpm-toolchain-sync.mjs'
21
+ } from './lib/dependency-policy-toolchain.mjs'
22
+ import { syncDockerfileNodeImages } from './lib/node-toolchain-sync.mjs'
23
+ import { syncDockerfilePnpmVersion } from './lib/pnpm-toolchain-sync.mjs'
24
+ import { fgDevkitRoot } from './lib/common.mjs'
24
25
 
25
26
  /**
26
27
  * @param {{ fgDevkitRoot: string, policyPath: string }} options
@@ -97,12 +98,10 @@ export function syncScaffoldVueDepsFromPolicy(options) {
97
98
  console.log('[sync-scaffold-vue-deps] Updated', scaffoldPkgPath)
98
99
  }
99
100
 
100
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
101
- const fgDevkitRoot = path.resolve(scriptDir, '..')
102
101
  const invokedPath = path.resolve(process.argv[1] ?? '')
103
102
  const selfPath = path.resolve(fileURLToPath(import.meta.url))
104
103
 
105
104
  if (invokedPath === selfPath) {
106
- const policyPath = resolveDependencyPolicyPath(scriptDir, process.cwd(), process.argv)
105
+ const policyPath = resolveDependencyPolicyPath(process.cwd(), process.argv)
107
106
  syncScaffoldVueDepsFromPolicy({ fgDevkitRoot, policyPath })
108
107
  }
@@ -4,7 +4,9 @@
4
4
  * - prettier.config.js — overwritten from fg-devkit prettier sync template
5
5
  * - eslint.config.js — overwritten from fg-devkit eslint sync template
6
6
  * - tsconfig.json — overwritten from fg-devkit tsconfig app sync template
7
- * - .fallowrc.json — overwritten from fg-devkit fallow sync template
7
+ *
8
+ * .fallowrc.json is not copied: `fgd dead-code` / `fgd fallow` use fg-devkit's config unless
9
+ * the repo has its own.
8
10
  *
9
11
  * This command is intentionally deterministic: each run rewrites files to the shared templates.
10
12
  *
@@ -17,26 +19,11 @@
17
19
 
18
20
  import fs from 'node:fs'
19
21
  import path from 'node:path'
20
- import { fileURLToPath } from 'node:url'
22
+ import { findFgDevkitPackageRoot } from './lib/common.mjs'
21
23
 
22
24
  const projectRoot = process.cwd()
23
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
24
-
25
- function findFgDevkitPackageRoot() {
26
- const candidates = [
27
- path.resolve(scriptDir, '..'),
28
- path.join(projectRoot, 'node_modules', 'fg-devkit'),
29
- path.join(projectRoot, 'node_modules', 'fds-vue-core', 'node_modules', 'fg-devkit'),
30
- ]
31
- for (const p of candidates) {
32
- if (fs.existsSync(path.join(p, 'package.json'))) {
33
- return p
34
- }
35
- }
36
- return null
37
- }
38
25
 
39
- const fgRoot = findFgDevkitPackageRoot()
26
+ const fgRoot = findFgDevkitPackageRoot(projectRoot)
40
27
  if (!fgRoot) {
41
28
  console.error(
42
29
  '[sync-tooling] Could not find fg-devkit (install fg-devkit or a package that bundles it, e.g. fds-vue-core).',
@@ -47,11 +34,10 @@ if (!fgRoot) {
47
34
  const prettierSrc = path.join(fgRoot, 'configs', 'prettier.sync-stub.js')
48
35
  const eslintStubSrc = path.join(fgRoot, 'configs', 'eslint.sync-stub.js')
49
36
  const tsconfigSrc = path.join(fgRoot, 'configs', 'tsconfig.app.sync.json')
50
- const fallowConfigSrc = path.join(fgRoot, 'configs', 'fallowrc.sync-stub.json')
51
37
 
52
- if (!fs.existsSync(prettierSrc) || !fs.existsSync(eslintStubSrc) || !fs.existsSync(tsconfigSrc) || !fs.existsSync(fallowConfigSrc)) {
38
+ if (!fs.existsSync(prettierSrc) || !fs.existsSync(eslintStubSrc) || !fs.existsSync(tsconfigSrc)) {
53
39
  console.error(
54
- '[sync-tooling] Missing prettier.sync-stub.js, eslint.sync-stub.js, tsconfig.app.sync.json, or fallowrc.sync-stub.json inside fg-devkit package.',
40
+ '[sync-tooling] Missing prettier.sync-stub.js, eslint.sync-stub.js, or tsconfig.app.sync.json inside fg-devkit package.',
55
41
  )
56
42
  process.exit(1)
57
43
  }
@@ -60,8 +46,7 @@ try {
60
46
  fs.copyFileSync(prettierSrc, path.join(projectRoot, 'prettier.config.js'))
61
47
  fs.copyFileSync(eslintStubSrc, path.join(projectRoot, 'eslint.config.js'))
62
48
  fs.copyFileSync(tsconfigSrc, path.join(projectRoot, 'tsconfig.json'))
63
- fs.copyFileSync(fallowConfigSrc, path.join(projectRoot, '.fallowrc.json'))
64
- console.log('[sync-tooling] Updated prettier.config.js, eslint.config.js, tsconfig.json, and .fallowrc.json.')
49
+ console.log('[sync-tooling] Updated prettier.config.js, eslint.config.js, and tsconfig.json.')
65
50
  } catch (err) {
66
51
  console.error(`[sync-tooling] ${err.message}`)
67
52
  process.exit(1)
@@ -16,10 +16,10 @@
16
16
 
17
17
  import fs from 'node:fs'
18
18
  import path from 'node:path'
19
- import { fileURLToPath } from 'node:url'
20
19
  import { spawnSync } from 'node:child_process'
21
20
 
22
- import { resolveDependencyPolicyPath } from './resolve-dependency-policy-path.mjs'
21
+ import { resolveDependencyPolicyPath } from './lib/resolve-dependency-policy-path.mjs'
22
+ import { fileDiffersFromHead, runGit, stageExistingFiles } from './lib/common.mjs'
23
23
 
24
24
  const PACKAGE_NAME = 'vite-plugin-vue-inspector'
25
25
  const IMPORT_LINE = `import Inspector from '${PACKAGE_NAME}'`
@@ -36,9 +36,9 @@ const VITE_CONFIG_CANDIDATES = [
36
36
  'vite.config.mjs',
37
37
  ]
38
38
 
39
- const scriptDir = path.dirname(fileURLToPath(import.meta.url))
40
39
  const cwd = process.cwd()
41
- const policyPath = resolveDependencyPolicyPath(scriptDir, cwd, process.argv)
40
+ const GIT = { cwd, tag: '[sync-vite-plugin-vue-inspector]' }
41
+ const policyPath = resolveDependencyPolicyPath(cwd, process.argv)
42
42
 
43
43
  function fail(message) {
44
44
  console.error(`[sync-vite-plugin-vue-inspector] ${message}`)
@@ -57,38 +57,6 @@ function runPnpm(args) {
57
57
  return result.status ?? 1
58
58
  }
59
59
 
60
- function runGit(args, options = {}) {
61
- const result = spawnSync('git', args, {
62
- stdio: options.capture ? 'pipe' : 'inherit',
63
- encoding: options.capture ? 'utf8' : undefined,
64
- cwd,
65
- env: process.env,
66
- })
67
- if (result.error) {
68
- fail(result.error.message)
69
- }
70
- return { status: result.status ?? 1, stdout: result.stdout ?? '' }
71
- }
72
-
73
- function fileDiffersFromHead(filePath) {
74
- const absolutePath = path.join(cwd, filePath)
75
- if (!fs.existsSync(absolutePath)) return false
76
-
77
- const tracked = runGit(['ls-files', '--error-unmatch', '--', filePath], { capture: true })
78
- if (tracked.status !== 0) {
79
- return true
80
- }
81
-
82
- const diff = runGit(['diff', '--quiet', 'HEAD', '--', filePath], { capture: true })
83
- return diff.status !== 0
84
- }
85
-
86
- function stageExistingFiles(files) {
87
- const existingFiles = files.filter((filePath) => fs.existsSync(path.join(cwd, filePath)))
88
- if (existingFiles.length === 0) return 0
89
- return runGit(['add', '--', ...existingFiles]).status
90
- }
91
-
92
60
  function resolvePluginVersion(policy) {
93
61
  return (
94
62
  policy.managedDependencies?.devDependencies?.[PACKAGE_NAME] ??
@@ -427,20 +395,20 @@ function installAndCommit(viteConfigName) {
427
395
  }
428
396
 
429
397
  const candidateFiles = ['package.json', 'pnpm-lock.yaml', viteConfigName].filter(Boolean)
430
- const filesToStage = candidateFiles.filter((filePath) => fileDiffersFromHead(filePath))
398
+ const filesToStage = candidateFiles.filter((filePath) => fileDiffersFromHead(filePath, GIT))
431
399
  if (filesToStage.length === 0) {
432
400
  console.log('[sync-vite-plugin-vue-inspector] No related changes to commit.')
433
401
  return
434
402
  }
435
403
 
436
- const stageExitCode = stageExistingFiles(filesToStage)
404
+ const stageExitCode = stageExistingFiles(filesToStage, GIT)
437
405
  if (stageExitCode !== 0) {
438
406
  process.exit(stageExitCode)
439
407
  }
440
408
 
441
409
  console.log(`[sync-vite-plugin-vue-inspector] Staged ${filesToStage.length} file(s)`)
442
410
  console.log(`[sync-vite-plugin-vue-inspector] Auto-committing: ${COMMIT_MESSAGE}`)
443
- const commitExitCode = runGit(['commit', '-m', COMMIT_MESSAGE]).status
411
+ const commitExitCode = runGit(['commit', '-m', COMMIT_MESSAGE], GIT).status
444
412
  if (commitExitCode !== 0) {
445
413
  process.exit(commitExitCode)
446
414
  }
@@ -18,7 +18,7 @@ import {
18
18
  hasReleaseNotesConfig,
19
19
  readPreviewFiles,
20
20
  runSyncUserChangelog,
21
- } from './release-notes-common.mjs'
21
+ } from './lib/release-notes-common.mjs'
22
22
 
23
23
  const scriptDir = path.dirname(fileURLToPath(import.meta.url))
24
24
  const cwd = process.cwd()