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
20 changes: 20 additions & 0 deletions esbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { build } from 'esbuild';

const result = await build({
entryPoints: ['src/index.ts'],
bundle: true,
minify: false,
splitting: true,
platform: 'node',
outdir: 'dist',
format: 'esm',
loader: {
'.node': 'file',
'.cc': 'file',
},
// external: ['node-pty'],
// packages: 'external',
logLevel: 'debug',
});

console.log(result);
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "homebrew-plugin",
"version": "1.0.0",
"name": "default",
"version": "0.11.0",
"description": "",
"main": "dist/index.js",
"scripts": {
Expand All @@ -12,7 +12,8 @@
"test:integration": "vitest test/**/*.test.ts",
"test": "vitest",
"rollup": "rollup -c",
"build": "tsx ./scripts/build.ts"
"build": "tsx ./scripts/build.ts",
"deploy": "tsx ./scripts/deploy.ts"
},
"keywords": [],
"author": "",
Expand All @@ -22,20 +23,22 @@
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
"semver": "^7.6.0",
"codify-plugin-lib": "1.0.107",
"codify-schemas": "1.0.52",
"codify-plugin-lib": "1.0.132",
"codify-schemas": "1.0.63",
"chalk": "^5.3.0",
"debug": "^4.3.4",
"plist": "^3.1.0",
"lodash.isequal": "^4.5.0",
"strip-ansi": "^7.1.0"
"strip-ansi": "^7.1.0",
"nanoid": "^5.0.9"
},
"devDependencies": {
"rollup": "^4.12.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-typescript": "^11.1.6",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^6.0.2",
"@rollup/plugin-terser": "^0.4.4",
"@oclif/prettier-config": "^0.2.1",
"@oclif/test": "^3",
Expand All @@ -47,7 +50,7 @@
"@types/debug": "4.1.12",
"@types/plist": "^3.0.5",
"@types/lodash.isequal": "^4.5.8",
"codify-plugin-test": "0.0.26",
"codify-plugin-test": "0.0.47",
"commander": "^12.1.0",
"eslint": "^8.51.0",
"eslint-config-oclif": "^5",
Expand Down
7 changes: 4 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import typescript from '@rollup/plugin-typescript';
import json from '@rollup/plugin-json';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import nodeResolve from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';
import typescript from '@rollup/plugin-typescript';

export default {
input: 'src/index.ts',
output: {
dir:'dist',
format: 'cjs'
},
external: ['@homebridge/node-pty-prebuilt-multiarch'],
plugins: [
json(),
nodeResolve({ exportConditions: ['node']}),
nodeResolve({ exportConditions: ['node'] }),
typescript(),
commonjs(),
terser()
Expand Down
12 changes: 10 additions & 2 deletions scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { Ajv } from 'ajv';
import { IpcMessage, IpcMessageSchema, MessageStatus, ResourceSchema } from 'codify-schemas';
import mergeJsonSchemas from 'merge-json-schemas';
import { ChildProcess, fork } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import * as url from 'node:url';

import { codifySpawn } from '../src/utils/codify-spawn.js';

Expand Down Expand Up @@ -88,8 +91,13 @@ const mergedSchemas = [...schemasMap.entries()].map(([type, schema]) => {
await codifySpawn('rm -rf ./dist')
await codifySpawn('npm run rollup'); // re-run rollup without building for es

console.log('JSON Schemas for all resources')
console.log(JSON.stringify(mergedSchemas, null, 2));
console.log('Generated JSON Schemas for all resources')

const distFolder = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '..', 'dist');
const schemaOutputPath = path.resolve(distFolder, 'schemas.json');
fs.writeFileSync(schemaOutputPath, JSON.stringify(mergedSchemas, null, 2));

console.log('Successfully wrote schema to ./dist/schemas.json')

// eslint-disable-next-line n/no-process-exit,unicorn/no-process-exit
process.exit(0)
Expand Down
21 changes: 21 additions & 0 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as cp from 'node:child_process';
import path from 'node:path';
import * as url from 'node:url';

// This should run the build
cp.spawnSync('source ~/.zshrc; npm run build', { shell: 'zsh', stdio: 'inherit' });

const version = process.env.npm_package_version;
if (!version) {
throw new Error('Unable to find version');
}

const name = process.env.npm_package_name;
if (!name) {
throw new Error('Unable to find package name');
}

console.log(`Uploading plugin ${name}, version ${version} to cloudflare!`)

const outputFilePath = path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '..', 'dist', 'index.js')
cp.spawnSync(`source ~/.zshrc; npx wrangler r2 object put plugins/${name}/${version}/index.js --file=${outputFilePath}`, { shell: 'zsh', stdio: 'inherit' });
28 changes: 16 additions & 12 deletions scripts/run-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,30 @@ async function run(cmd: string, debug: boolean, simple = true) {
const [_, ip] = data.toString().match(IP_REGEX);

console.log(`Copying ssh keys to ${ip}`)
spawnSync(`source $HOME/.zshrc; sshpass -p admin ssh-copy-id -o "StrictHostKeyChecking=no" admin@${ip}`, { stdio: 'inherit', shell: 'zsh' });
// spawnSync(`source $HOME/.zshrc; sshpass -p admin ssh-copy-id -o "StrictHostKeyChecking=no" admin@${ip}`, { stdio: 'inherit', shell: 'zsh' });

console.log('Enabling port forwarding')
const portForward1 = spawn(`ssh -L 9229:localhost:9229 -Nf admin@${ip}`, { stdio: 'pipe', shell: 'zsh' });
const sshStatement1 = `ssh${ Array.from({ length: 20 }, (i: number) => i + 9000).map((i) => ` -L ${i}:localhost:${i}`)} admin@${ip}`;
const sshStatement2 = `source $HOME/.zshrc; sshpass -p admin ssh -L 9221:localhost:9221 -L 9229:localhost:9229 -N -o "StrictHostKeyChecking=no" admin@${ip}`

const portForward1 = spawn(sshStatement2, { stdio: 'pipe', shell: 'zsh' });
portForward1.stderr.pipe(process.stdout)
portForward1.stdout.on('data', data => {
console.log(data.toString());
if (data.toString().includes('Address already in use')) {
throw new Error('Port 9229 already in use!')
}
})
console.log('Enabled on port 9229')

const portForward2 = spawn(`ssh -L 9221:localhost:9221 -Nf admin@${ip}`, { stdio: 'pipe', shell: 'zsh' });
portForward2.stdout.on('data', data => {
console.log(data.toString());
if (data.toString().includes('Address already in use')) {
throw new Error('Port 9221 already in use!')
}
});
console.log('Enabled on port 9221')
// console.log('Enabled on port 9229')

// const portForward2 = spawn(`ssh -L 9221:localhost:9221 -Nf admin@${ip}`, { stdio: 'pipe', shell: 'zsh' });
// portForward2.stdout.on('data', data => {
// console.log(data.toString());
// if (data.toString().includes('Address already in use')) {
// throw new Error('Port 9221 already in use!')
// }
// });
// console.log('Enabled on port 9221')
}
})
}
Expand Down
13 changes: 6 additions & 7 deletions src/resources/asdf/asdf-global.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, } from 'codify-plugin-lib';
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, getPty, } from 'codify-plugin-lib';
import { ResourceConfig } from 'codify-schemas';
import os from 'node:os';
import path from 'node:path';
Expand Down Expand Up @@ -29,16 +29,15 @@ export class AsdfGlobalResource extends Resource<AsdfGlobalConfig> {
}

async refresh(parameters: Partial<AsdfGlobalConfig>): Promise<Partial<AsdfGlobalConfig> | Partial<AsdfGlobalConfig>[] | null> {
if ((await codifySpawn('which asdf', { throws: false })).status === SpawnStatus.ERROR) {
return null;
}
const $ = getPty();

if ((await codifySpawn(`asdf list ${parameters.plugin}`, { throws: false })).status === SpawnStatus.ERROR) {
const plugins = await $.spawnSafe(`asdf list ${parameters.plugin}`);
if (plugins.status === SpawnStatus.ERROR) {
return null;
}

// Only check for the installed version matches if it's not latest. The latest version could be out of date.
const installedVersions = new Set((await codifySpawn(`asdf list ${parameters.plugin}`))
const installedVersions = new Set(plugins
.data
.split(/\n/)
.filter(Boolean)
Expand All @@ -53,7 +52,7 @@ export class AsdfGlobalResource extends Resource<AsdfGlobalConfig> {
return null;
}

const { status } = await codifySpawn(`asdf current ${parameters.plugin}`, { throws: false, cwd: os.homedir() });
const { status } = await $.spawnSafe(`asdf current ${parameters.plugin}`, { cwd: os.homedir() });
return status === SpawnStatus.ERROR
? null
: parameters;
Expand Down
35 changes: 29 additions & 6 deletions src/resources/asdf/asdf-install.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, untildify, } from 'codify-plugin-lib';
import { CreatePlan, DestroyPlan, getPty, Resource, ResourceSettings, untildify, } from 'codify-plugin-lib';
import { ResourceConfig } from 'codify-schemas';
import * as fs from 'node:fs/promises';
import path from 'node:path';
Expand Down Expand Up @@ -26,12 +26,12 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
schema: AsdfInstallSchema,
parameterSettings: {
directory: { type: 'directory', inputTransformation: (input) => untildify(input) },
versions: { type: 'stateful', definition: new AsdfPluginVersionsParameter() }
versions: { type: 'array' }
},
import: {
requiredParameters: ['directory'],
refreshKeys: ['directory']
}
},
}
}

Expand All @@ -50,15 +50,17 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
}

async refresh(parameters: Partial<AsdfInstallConfig>): Promise<Partial<AsdfInstallConfig> | Partial<AsdfInstallConfig>[] | null> {
if ((await codifySpawn('which asdf', { throws: false })).status === SpawnStatus.ERROR) {
const $ = getPty();

if ((await $.spawnSafe('which asdf')).status === SpawnStatus.ERROR) {
return null;
}

if (parameters.directory) {
const desiredTools = await this.getToolVersions(parameters.directory);

for (const { plugin, version } of desiredTools) {
const { status, data } = await codifySpawn(`asdf current ${plugin}`, { throws: false, cwd: parameters.directory });
const { status, data } = await $.spawnSafe(`asdf current ${plugin}`, { cwd: parameters.directory });
if (status === SpawnStatus.ERROR || data.trim() === '') {
return null;
}
Expand All @@ -74,12 +76,25 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
};
}

if ((await codifySpawn('which asdf', { throws: false })).status === SpawnStatus.ERROR) {
// Directly check plugin version
const versionsQuery = await $.spawnSafe(`asdf list ${parameters.plugin}`);
if (versionsQuery.status === SpawnStatus.ERROR || versionsQuery.data.trim() === 'No versions installed') {
return null;
}

const latest = parameters.versions?.includes('latest')
? (await codifySpawn(`asdf latest ${parameters.plugin}`)).data.trim()
: null;

const versions = versionsQuery.data.split(/\n/)
.map((l) => l.trim())
.map((l) => l.replaceAll('*', ''))
.map((l) => l.trim() === latest ? 'latest' : l)
.filter(Boolean);

return {
plugin: parameters.plugin,
versions,
}
}

Expand All @@ -95,7 +110,10 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
}

await codifySpawn('asdf install', { cwd: plan.desiredConfig.directory });
return;
}

await codifySpawn(`asdf install ${plan.desiredConfig?.plugin} ${plan.desiredConfig.versions?.join(' ')}`);
}

async destroy(plan: DestroyPlan<AsdfInstallConfig>): Promise<void> {
Expand All @@ -106,7 +124,12 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
for (const { plugin, version } of desiredTools) {
await codifySpawn(`asdf uninstall ${plugin} ${version}`);
}

return;
}

// Other path is uninstalled through the stateful parameter
await codifySpawn(`asdf uninstall ${plan.currentConfig?.plugin} ${plan.currentConfig.versions?.join(' ')}`);
}

private async getToolVersions(directory: string): Promise<Array<{ plugin: string; version: string }>> {
Expand Down
25 changes: 15 additions & 10 deletions src/resources/asdf/asdf-local.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { CreatePlan, DestroyPlan, ModifyPlan, ParameterChange, Resource, ResourceSettings, } from 'codify-plugin-lib';
import {
CreatePlan,
DestroyPlan,
getPty,
ModifyPlan,
ParameterChange,
Resource,
ResourceSettings,
} from 'codify-plugin-lib';
import { ResourceConfig } from 'codify-schemas';
import * as fs from 'node:fs';
import path from 'node:path';
Expand Down Expand Up @@ -66,16 +74,15 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
}

async refresh(parameters: Partial<AsdfLocalConfig>): Promise<Partial<AsdfLocalConfig> | Partial<AsdfLocalConfig>[] | null> {
if ((await codifySpawn('which asdf', { throws: false })).status === SpawnStatus.ERROR) {
return null;
}
const $ = getPty();

if ((await codifySpawn(`asdf list ${parameters.plugin}`, { throws: false })).status === SpawnStatus.ERROR) {
const plugins = await $.spawnSafe(`asdf list ${parameters.plugin}`);
if (plugins.status === SpawnStatus.ERROR) {
return null;
}

// Only check for the installed version matches if it's not latest. The latest version could be out of date.
const installedVersions = new Set((await codifySpawn(`asdf list ${parameters.plugin}`))
const installedVersions = new Set(plugins
.data
.split(/\n/)
.filter(Boolean)
Expand All @@ -91,7 +98,7 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
}

if (parameters.directory) {
const { status, data } = await codifySpawn(`asdf current ${parameters.plugin}`, { throws: false, cwd: parameters.directory });
const { status, data } = await $.spawnSafe(`asdf current ${parameters.plugin}`, { cwd: parameters.directory });

if (status === SpawnStatus.ERROR || data.trim() === '') {
return null;
Expand All @@ -109,7 +116,7 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
let versionUpToDate = true;
let latestVersion = null;
for (const dir of parameters.directories!) {
const { status, data } = await codifySpawn(`asdf current ${parameters.plugin}`, { throws: false, cwd: dir });
const { status, data } = await $.spawnSafe(`asdf current ${parameters.plugin}`, { cwd: dir });
if (status === SpawnStatus.ERROR || data.trim() === '') {
continue;
}
Expand Down Expand Up @@ -173,9 +180,7 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
}

for (const dir of plan.currentConfig.directories!) {
console.log(path.join(dir, '.tool-versions'))
await FileUtils.removeLineFromFile(path.join(dir, '.tool-versions'), plan.currentConfig.plugin);
console.log(fs.readFileSync(path.join(dir, '.tool-versions')).toString());
}
}
}
3 changes: 1 addition & 2 deletions src/resources/asdf/asdf-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, SpawnStatus, } from 'codify-plugin-lib';
import { CreatePlan, DestroyPlan, Resource, ResourceSettings, SpawnStatus, untildify } from 'codify-plugin-lib';
import { ResourceConfig } from 'codify-schemas';

import { codifySpawn } from '../../utils/codify-spawn.js';
Expand Down Expand Up @@ -37,7 +37,6 @@ export class AsdfPluginResource extends Resource<AsdfPluginConfig> {
.map((l) => l.trim())
.map((l) => l.replaceAll('*', ''))
.map((l) => {
console.log(l);
const matches = l.match(PLUGIN_LIST_REGEX)
if (!matches) {
return null;
Expand Down
Loading
Loading