Skip to content

Commit cb2e758

Browse files
feat!: add resource imports (#10)
BREAKING CHANGE: removed remote parameter from git-clone resource * Upgraded to latest lib version and fixed schemas to support imports * Added import requiredParameters and fixed bugs * Improved path import
1 parent a163425 commit cb2e758

File tree

18 files changed

+206
-151
lines changed

18 files changed

+206
-151
lines changed

package-lock.json

Lines changed: 19 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
"ajv": "^8.12.0",
2222
"ajv-formats": "^2.1.1",
2323
"semver": "^7.6.0",
24-
"codify-plugin-lib": "1.0.88",
25-
"codify-schemas": "1.0.45",
24+
"codify-plugin-lib": "1.0.100",
25+
"codify-schemas": "1.0.52",
2626
"chalk": "^5.3.0",
2727
"debug": "^4.3.4",
2828
"plist": "^3.1.0"

src/resources/asdf/asdf-global.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ export class AsdfGlobalResource extends Resource<AsdfGlobalConfig> {
1818
id: 'asdf-global',
1919
dependencies: ['asdf', 'asdf-plugin'],
2020
schema: AsdfGlobalSchema,
21+
import: {
22+
requiredParameters: ['plugin'],
23+
refreshKeys: ['plugin', 'version'],
24+
defaultRefreshValues: {
25+
version: 'latest'
26+
}
27+
}
2128
}
2229
}
2330

src/resources/asdf/asdf-install-schema.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,13 @@
2020
"description": "The directory to run the install command"
2121
}
2222
},
23+
"oneOf": [
24+
{
25+
"required": ["plugin", "versions"]
26+
},
27+
{
28+
"required": ["directory"]
29+
}
30+
],
2331
"additionalProperties": false
2432
}

src/resources/asdf/asdf-install.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import * as fs from 'node:fs/promises';
44
import path from 'node:path';
55

66
import { SpawnStatus, codifySpawn } from '../../utils/codify-spawn.js';
7+
import { FileUtils } from '../../utils/file-utils.js';
78
import AsdfInstallSchema from './asdf-install-schema.json';
89
import { AsdfPluginVersionsParameter } from './version-parameter.js';
9-
import { FileUtils } from '../../utils/file-utils.js';
1010

1111
export interface AsdfInstallConfig extends ResourceConfig {
1212
plugin?: string;
@@ -28,6 +28,10 @@ export class AsdfInstallResource extends Resource<AsdfInstallConfig> {
2828
directory: { type: 'directory', inputTransformation: (input) => untildify(input) },
2929
versions: { type: 'stateful', definition: new AsdfPluginVersionsParameter() }
3030
},
31+
import: {
32+
requiredParameters: ['directory'],
33+
refreshKeys: ['directory']
34+
}
3135
}
3236
}
3337

src/resources/asdf/asdf-local.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
3636
version: {
3737
canModify: true,
3838
}
39+
},
40+
import: {
41+
requiredParameters: ['plugin', 'directory'],
42+
refreshKeys: ['plugin', 'version', 'directory'],
43+
defaultRefreshValues: {
44+
version: 'latest',
45+
}
3946
}
4047
}
4148
}
@@ -85,6 +92,7 @@ export class AsdfLocalResource extends Resource<AsdfLocalConfig> {
8592

8693
if (parameters.directory) {
8794
const { status, data } = await codifySpawn(`asdf current ${parameters.plugin}`, { throws: false, cwd: parameters.directory });
95+
8896
if (status === SpawnStatus.ERROR || data.trim() === '') {
8997
return null;
9098
}

src/resources/aws-cli/profile/aws-profile.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ export class AwsProfileResource extends Resource<AwsProfileConfig> {
3232
output: { default: 'json' },
3333
profile: { default: 'default' },
3434
},
35-
inputTransformation: CSVCredentialsParameter.transform
35+
inputTransformation: CSVCredentialsParameter.transform,
36+
import: {
37+
requiredParameters: ['profile']
38+
}
3639
};
3740
}
3841

src/resources/git/clone/git-clone-schema.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@
44
"title": "Git-clone resource",
55
"type": "object",
66
"properties": {
7-
"remote": {
8-
"type": "string",
9-
"description": "Remote tracking url to clone repo from. Equivalent to repository and only one should be specified"
10-
},
117
"repository": {
128
"type": "string",
13-
"description": "Remote repository to clone repo from. Equivalent to remote and only one should be specified"
9+
"description": "Remote repository to clone repo from."
1410
},
1511
"parentDirectory": {
1612
"type": "string",
@@ -25,5 +21,9 @@
2521
"description": "Automatically verifies the ssh connection for ssh git clones. Defaults to true."
2622
}
2723
},
28-
"additionalProperties": false
24+
"additionalProperties": false,
25+
"oneOf": [
26+
{ "required": ["repository", "directory"] },
27+
{ "required": ["repository", "parentDirectory"] }
28+
]
2929
}

src/resources/git/clone/git-clone.ts

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CreatePlan, Resource, ResourceSettings } from 'codify-plugin-lib';
1+
import { CreatePlan, DestroyPlan, Resource, ResourceSettings } from 'codify-plugin-lib';
22
import { ResourceConfig } from 'codify-schemas';
33
import path from 'node:path';
44

@@ -12,8 +12,7 @@ export interface GitCloneConfig extends ResourceConfig {
1212
autoVerifySSH: boolean
1313
directory?: string,
1414
parentDirectory?: string,
15-
remote?: string,
16-
repository?: string,
15+
repository: string,
1716
}
1817

1918
export class GitCloneResource extends Resource<GitCloneConfig> {
@@ -22,65 +21,52 @@ export class GitCloneResource extends Resource<GitCloneConfig> {
2221
id: 'git-clone',
2322
schema: Schema,
2423
parameterSettings: {
25-
autoVerifySSH: { default: true },
24+
parentDirectory: { type: 'directory' },
25+
directory: { type: 'directory' },
26+
autoVerifySSH: { type: 'setting', default: true },
2627
},
27-
}
28-
}
29-
30-
override async validate(parameters: Partial<GitCloneConfig>): Promise<void> {
31-
if (parameters.parentDirectory && parameters.directory) {
32-
throw new Error('Cannot specify both parentDirectory and directory together')
33-
}
34-
35-
if (parameters.remote && parameters.repository) {
36-
throw new Error('Cannot specify both remote and repository together')
28+
import: {
29+
requiredParameters: ['directory']
30+
}
3731
}
3832
}
3933

4034
override async refresh(parameters: Partial<GitCloneConfig>): Promise<Partial<GitCloneConfig> | null> {
41-
const repositoryUrl = parameters.repository?? parameters.remote!;
42-
4335
if (parameters.parentDirectory) {
44-
const parentDirectory = path.resolve(untildify(parameters.parentDirectory));
45-
46-
const folderName = this.extractBasename(repositoryUrl);
36+
const folderName = this.extractBasename(parameters.repository!);
4737
if (!folderName) {
4838
throw new Error('Invalid git repository or remote name. Un-able to parse');
4939
}
5040

51-
const fullPath = path.join(parentDirectory, folderName);
41+
const fullPath = path.join(parameters.parentDirectory, folderName);
5242

5343
const exists = await FileUtils.checkDirExistsOrThrowIfFile(fullPath);
5444
if (!exists) {
5545
return null;
5646
}
5747

5848
const { data: url } = await codifySpawn('git config --get remote.origin.url', { cwd: fullPath });
59-
if (this.extractBasename(url) !== folderName) {
60-
console.log(this.extractBasename(url))
61-
console.log(folderName)
62-
throw new Error(`Folder found at location: '${fullPath}'. However the remote url '${url}' repo does not match desired repo '${repositoryUrl}'`);
63-
}
6449

65-
return parameters;
50+
return {
51+
parentDirectory: parameters.parentDirectory,
52+
repository: url.trim(),
53+
autoVerifySSH: parameters.autoVerifySSH,
54+
}
6655
}
6756

6857
if (parameters.directory) {
69-
const directory = path.resolve(untildify(parameters.directory));
70-
71-
const exists = await FileUtils.checkDirExistsOrThrowIfFile(directory);
58+
const exists = await FileUtils.checkDirExistsOrThrowIfFile(parameters.directory);
7259
if (!exists) {
7360
return null;
7461
}
7562

76-
const { data: url } = await codifySpawn('git config --get remote.origin.url', { cwd: directory });
77-
if (this.extractBasename(url) !== this.extractBasename(repositoryUrl)) {
78-
console.log(this.extractBasename(url))
79-
console.log(this.extractBasename(url))
80-
throw new Error(`Folder found at location: '${directory}'. However the remote url '${url}' does not match desired url '${repositoryUrl}'`);
81-
}
63+
const { data: url } = await codifySpawn('git config --get remote.origin.url', { cwd: parameters.directory });
8264

83-
return parameters;
65+
return {
66+
directory: parameters.directory,
67+
repository: url.trim(),
68+
autoVerifySSH: parameters.autoVerifySSH,
69+
}
8470
}
8571

8672
throw new Error('Either directory or parent directory must be supplied');
@@ -89,24 +75,25 @@ export class GitCloneResource extends Resource<GitCloneConfig> {
8975

9076
override async create(plan: CreatePlan<GitCloneConfig>): Promise<void> {
9177
const config = plan.desiredConfig;
92-
const repositoryUrl = config.repository ?? config.remote!;
9378

9479
if (plan.desiredConfig.autoVerifySSH) {
95-
await this.autoVerifySSHForFirstAttempt(repositoryUrl)
80+
await this.autoVerifySSHForFirstAttempt(config.repository)
9681
}
9782

9883
if (config.parentDirectory) {
9984
const parentDirectory = path.resolve(untildify(config.parentDirectory));
10085
await FileUtils.createDirIfNotExists(parentDirectory);
101-
await codifySpawn(`git clone --progress ${repositoryUrl}`, { cwd: parentDirectory });
86+
await codifySpawn(`git clone --progress ${config.repository}`, { cwd: parentDirectory });
10287
} else {
10388
const directory = path.resolve(untildify(config.directory!));
104-
await codifySpawn(`git clone --progress ${repositoryUrl} ${directory}`);
89+
await codifySpawn(`git clone --progress ${config.repository} ${directory}`);
10590
}
10691
}
10792

108-
override async destroy(): Promise<void> {
93+
override async destroy(plan: DestroyPlan<GitCloneConfig>): Promise<void> {
10994
// Do nothing here. We don't want to destroy a user's repository.
95+
throw new Error(`The git-clone resource is not designed to delete folders.
96+
Please delete ${plan.currentConfig.directory ?? (plan.currentConfig.parentDirectory! + this.extractBasename(plan.currentConfig.repository))} manually and re-apply`);
11097
}
11198

11299
// Converts https://github.com/kevinwang5658/codify-homebrew-plugin.git => codify-homebrew-plugin

src/resources/java/jenv/java-versions-parameter.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,13 @@ export class JenvAddParameter extends ArrayStatefulParameter<JenvConfig, string>
1818
* 17.0.11
1919
* openjdk64-17.0.11
2020
*/
21-
const versions = new Set(
21+
return [...new Set(
2222
data
2323
.split(/\n/)
2424
// Regex to split out the version part
2525
.map((v) => this.getFirstRegexGroup(/^[ *] ([\d.A-Za-z-]+)[ \\n]?/g, v))
26-
);
27-
28-
return desired
29-
?.filter((v) => versions.has(v))
30-
?.filter(Boolean) ?? null;
26+
.filter(Boolean) as string[]
27+
)]
3128
}
3229

3330
override async addItem(param: string): Promise<void> {

0 commit comments

Comments
 (0)