Skip to content

Commit fd70778

Browse files
committed
refactor(tui): modularize monolithic tui.go, secure concurrency, and clean style extraction
1 parent af70d83 commit fd70778

14 files changed

Lines changed: 3652 additions & 3621 deletions

File tree

bin/cli.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,11 @@ export async function runCli(name, argv, options = {}) {
468468
})
469469
process.exit(0)
470470
}
471-
runNpmInstall(kind, pkgName, workspaceRoot)
471+
try {
472+
await runNpmInstall(kind, pkgName, workspaceRoot)
473+
} catch (error) {
474+
fail(error.message ?? String(error))
475+
}
472476
} else {
473477
try {
474478
await runWorkspaceInstall({

bin/lib/cpFormat.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export function formatCatalogRowPlain(item, ctx = {}) {
160160

161161
// 3.5 DIR Column (4 chars)
162162
let dirTag = ''
163-
const isMissing = item.installed && !item.localSource
163+
const isMissing = item.installed && !item.localSource && !item.inPackageJson
164164
if (isMissing) {
165165
dirTag = `{red-fg}MISS{/}`
166166
} else if (item.localSource) {
@@ -321,7 +321,7 @@ export function formatDetailPanel(item, targetDir, colors = DEFAULT_COLORS, widt
321321
lines.push(` {${c.muted}-fg}${item.description.slice(0, maxDescLen)}{/}`)
322322
}
323323

324-
const isMissing = item.installed && !item.localSource
324+
const isMissing = item.installed && !item.localSource && !item.inPackageJson
325325
if (isMissing) {
326326
lines.push(` {red-fg}{bold}⚠ WARNING: Local workspace folder is missing!{/}{/}`)
327327
}

bin/lib/install.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -463,16 +463,22 @@ export async function runWorkspaceInstall({
463463
}
464464

465465
export function runNpmInstall(kind, pkgName, workspaceRoot, stdio = 'inherit') {
466-
const nxTarget = KINDS[kind].nx
467-
const child = spawn('pnpm', ['nx', 'run', nxTarget, `--name=${pkgName}`], {
468-
stdio,
469-
shell: true,
470-
cwd: workspaceRoot,
471-
})
472-
child.on('exit', (code) => {
473-
if (stdio === 'inherit') process.exit(code ?? 1)
466+
return new Promise((resolve, reject) => {
467+
const nxTarget = KINDS[kind].nx
468+
const child = spawn('pnpm', ['nx', 'run', nxTarget, `--name=${pkgName}`], {
469+
stdio,
470+
shell: true,
471+
cwd: workspaceRoot,
472+
})
473+
child.on('error', reject)
474+
child.on('exit', (code) => {
475+
if (code === 0) {
476+
resolve()
477+
} else {
478+
reject(new Error(`Installation failed with exit code ${code}`))
479+
}
480+
})
474481
})
475-
return child
476482
}
477483

478484
/** Preview label for TUI list rows */

bin/lib/installWizardFlow.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ export async function runStartupInstallFlow(ctx, { isStartup = false } = {}) {
440440

441441
const merged = mergeInstalled(catalog, config, deps, workspaceRoot)
442442
const missingAppsModules = merged
443-
.filter((item) => item.installed && !item.localSource && item.kind !== 'theme')
443+
.filter((item) => item.installed && !item.localSource && !item.inPackageJson && item.kind !== 'theme')
444444
.map((item) => item.name)
445445

446446
const desiredTheme = ctx.getPendingTheme() ?? config.theme

go/bridge/bridge.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ func getBridgePath(root string) string {
127127
// ReadWorkspaceContext runs the node bridge with --read
128128
func ReadWorkspaceContext(root string) (*WorkspaceContext, error) {
129129
cmd := exec.Command("node", getBridgePath(root), "--read")
130+
cmd.Dir = root
130131
var stdout, stderr bytes.Buffer
131132
cmd.Stdout = &stdout
132133
cmd.Stderr = &stderr
@@ -150,6 +151,7 @@ func ReadCatalog(root string, force bool) (*CatalogResponse, error) {
150151
args = append(args, "--force")
151152
}
152153
cmd := exec.Command("node", args...)
154+
cmd.Dir = root
153155
var stdout, stderr bytes.Buffer
154156
cmd.Stdout = &stdout
155157
cmd.Stderr = &stderr
@@ -169,6 +171,7 @@ func ReadCatalog(root string, force bool) (*CatalogResponse, error) {
169171
// WriteChanges feeds the write payload to the node bridge via stdin
170172
func WriteChanges(root string, payload *WritePayload) error {
171173
cmd := exec.Command("node", getBridgePath(root), "--write")
174+
cmd.Dir = root
172175
var stdout, stderr bytes.Buffer
173176
cmd.Stdout = &stdout
174177
cmd.Stderr = &stderr

go/main.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,15 @@ func main() {
2020
}
2121

2222
model := tui.NewModel(root)
23-
p = tea.NewProgram(model, tea.WithAltScreen())
24-
tui.Program = p
23+
p = tea.NewProgram(&model, tea.WithAltScreen())
2524

2625
finalModel, err := p.Run()
2726
if err != nil {
2827
fmt.Printf("Alas, there's been an error: %v", err)
2928
os.Exit(1)
3029
}
3130

32-
if m, ok := finalModel.(tui.TuiModel); ok && m.ExitCode != 0 {
31+
if m, ok := finalModel.(*tui.TuiModel); ok && m.ExitCode != 0 {
3332
os.Exit(m.ExitCode)
3433
}
3534
}

0 commit comments

Comments
 (0)