Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "default",
"version": "1.6.1",
"version": "1.7.1",
"description": "Default plugin for Codify - provides 50+ declarative resources for managing development tools and system configuration across macOS and Linux",
"main": "dist/index.js",
"scripts": {
Expand Down
18 changes: 18 additions & 0 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ if (!isBeta) {
// Build and deploy completions as well.
console.log('Deploying completions...')
cp.spawnSync('source ~/.zshrc; npm run deploy:completions' , { shell: 'zsh', stdio: 'inherit' })

// Trigger vector reindex so search embeddings reflect the latest resources
console.log('Triggering vector reindex...')
const reindexKey = process.env.REINDEX_API_KEY
if (!reindexKey) {
console.warn('REINDEX_API_KEY not set — skipping reindex')
} else {
const res = await fetch('https://api.codifycli.com/v1/embeddings/reindex', {
method: 'POST',
headers: { Authorization: `Bearer ${reindexKey}` },
})
if (!res.ok) {
console.error(`Reindex failed: ${res.status} ${await res.text()}`)
} else {
const body = await res.json() as { resources_processed: number; templates_processed: number }
console.log(`Reindex complete — resources: ${body.resources_processed}, templates: ${body.templates_processed}`)
}
}
}

async function uploadResources(prerelease: boolean) {
Expand Down
10 changes: 5 additions & 5 deletions src/resources/homebrew/casks-parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class CasksParameter extends StatefulParameter<HomebrewConfig, string[]>
async refresh(desired: string[], config: Partial<HomebrewConfig> | null): Promise<null | string[]> {
const $ = getPty();

const caskQuery = await $.spawnSafe('brew list --casks -1 --full-name')
const caskQuery = await $.spawnSafe('brew list --casks -1 --full-name', { env: { NONINTERACTIVE: 1 }})

if (caskQuery.status === SpawnStatus.SUCCESS && caskQuery.data !== null && caskQuery.data !== undefined) {
const installedCasks = caskQuery.data
Expand Down Expand Up @@ -100,7 +100,7 @@ export class CasksParameter extends StatefulParameter<HomebrewConfig, string[]>
for (const cask of casksToInstall) {
const result = await $.spawnSafe(`brew install --casks ${cask}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})

if (result.status === SpawnStatus.SUCCESS) {
Expand All @@ -111,7 +111,7 @@ export class CasksParameter extends StatefulParameter<HomebrewConfig, string[]>
if (result.data?.includes('It seems there is already an App at')) {
const adoptResult = await $.spawnSafe(`brew install --casks --adopt ${cask}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})

if (adoptResult.status === SpawnStatus.SUCCESS) {
Expand All @@ -133,7 +133,7 @@ export class CasksParameter extends StatefulParameter<HomebrewConfig, string[]>
const $ = getPty();
const result = await $.spawnSafe(`brew uninstall ${casks.join(' ')}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})

if (result.status === SpawnStatus.SUCCESS) {
Expand All @@ -153,7 +153,7 @@ export class CasksParameter extends StatefulParameter<HomebrewConfig, string[]>
const result = (await $.spawn(
`brew info -q --json=v2 ${casks.map((c) => `"${c}"`).join(' ')}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})
)
.data
Expand Down
10 changes: 6 additions & 4 deletions src/resources/homebrew/formulae-parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export class FormulaeParameter extends StatefulParameter<HomebrewConfig, string[

override async refresh(desired: unknown, config: Partial<HomebrewConfig>): Promise<null | string[]> {
const $ = getPty();
const formulaeQuery = await $.spawnSafe(`brew list --formula -1 --full-name ${config.onlyPlanUserInstalled ? '--installed-on-request' : ''}`)
const formulaeQuery = await $.spawnSafe(`brew list --formula -1 --full-name ${config.onlyPlanUserInstalled ? '--installed-on-request' : ''}`,
{ env: { NONINTERACTIVE: 1 }}
)

if (formulaeQuery.status === SpawnStatus.SUCCESS && formulaeQuery.data !== null && formulaeQuery.data !== undefined) {
return formulaeQuery.data
Expand Down Expand Up @@ -59,7 +61,7 @@ export class FormulaeParameter extends StatefulParameter<HomebrewConfig, string[
const $ = getPty();
const result = await $.spawnSafe(`brew install --formulae ${formulae.join(' ')}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})

if (result.status === SpawnStatus.SUCCESS) {
Expand All @@ -75,9 +77,9 @@ export class FormulaeParameter extends StatefulParameter<HomebrewConfig, string[
}

const $ = getPty();
const result = await $.spawnSafe(`HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall ${formulae.join(' ')}`, {
const result = await $.spawnSafe(`brew uninstall ${formulae.join(' ')}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }
})

if (result.status === SpawnStatus.SUCCESS) {
Expand Down
4 changes: 2 additions & 2 deletions src/resources/homebrew/homebrew.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export class HomebrewResource extends Resource<HomebrewConfig> {
override async refresh(parameters: Partial<HomebrewConfig>): Promise<Partial<HomebrewConfig> | null> {
const $ = getPty();

const homebrewInfo = await $.spawnSafe('brew config');
const homebrewInfo = await $.spawnSafe('brew config', { env: { HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 }});
if (homebrewInfo.status === SpawnStatus.ERROR) {
return null;
}
Expand Down Expand Up @@ -126,7 +126,7 @@ export class HomebrewResource extends Resource<HomebrewConfig> {
return;
}

const homebrewInfo = await $.spawn('brew config', { interactive: true });
const homebrewInfo = await $.spawn('brew config', { interactive: true, env: { NONINTERACTIVE: 1 } });
const homebrewDirectory = this.getCurrentLocation(homebrewInfo.data)

if (homebrewDirectory === '/opt/homebrew') {
Expand Down
6 changes: 3 additions & 3 deletions src/resources/homebrew/tap-parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class TapsParameter extends StatefulParameter<HomebrewConfig, string[]> {
override async refresh(): Promise<null | string[]> {
const $ = getPty();

const tapsQuery = await $.spawnSafe('brew tap')
const tapsQuery = await $.spawnSafe('brew tap', { env: { NONINTERACTIVE: 1 }})
if (tapsQuery.status === SpawnStatus.SUCCESS && tapsQuery.data !== null && tapsQuery.data !== undefined) {
return tapsQuery.data
.split('\n')
Expand Down Expand Up @@ -49,7 +49,7 @@ export class TapsParameter extends StatefulParameter<HomebrewConfig, string[]> {
for (const tap of taps) {
await $.spawn(`brew tap ${tap}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 },
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 },
});
}
}
Expand All @@ -63,7 +63,7 @@ export class TapsParameter extends StatefulParameter<HomebrewConfig, string[]> {
for (const tap of taps) {
await $.spawn(`brew untap ${tap}`, {
interactive: true,
env: { HOMEBREW_NO_AUTO_UPDATE: 1 },
env: { HOMEBREW_NO_AUTO_UPDATE: 1, HOMEBREW_NO_ASK: 1, NONINTERACTIVE: 1 },
});
}
}
Expand Down
15 changes: 15 additions & 0 deletions test/homebrew/default.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ describe('Homebrew main resource integration tests', { skip: !Utils.isMacOS() },
});
});

it('Installs formulae with dependencies without prompting (HOMEBREW_NO_ASK)', { timeout: 300000 }, async () => {
// ripgrep depends on pcre2; without HOMEBREW_NO_ASK brew would interactively ask
// whether to install the dependency, hanging the process
await PluginTester.fullTest(pluginPath, [{
type: 'homebrew',
formulae: ['ripgrep'],
}], {
skipUninstall: true,
validateApply: async () => {
expect(await testSpawn('which rg')).toMatchObject({ status: SpawnStatus.SUCCESS });
expect(await testSpawn('brew list pcre2')).toMatchObject({ status: SpawnStatus.SUCCESS });
}
});
});

it('Can handle casks that were already installed by skipping in the plan', { timeout: 300000 }, async () => {
if (!Utils.isMacOS()) {
return;
Expand Down
Loading