Skip to content

Commit 7e4db19

Browse files
committed
feat: Added default values for resources that already exist in the project and fixed bug with yoga memory management for large imports
1 parent 6717f38 commit 7e4db19

File tree

6 files changed

+286
-75
lines changed

6 files changed

+286
-75
lines changed

codify.json

Lines changed: 205 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,212 @@
1212
"hashicorp/tap",
1313
"homebrew/services"
1414
],
15-
"formulae": [
16-
"asciinema"
17-
],
1815
"casks": [
19-
"firefox"
16+
"android-commandlinetools",
17+
"android-studio",
18+
"mitmproxy"
19+
],
20+
"formulae": [
21+
"ack",
22+
"asciinema",
23+
"ca-certificates",
24+
"cairo",
25+
"cirrus",
26+
"expect",
27+
"fontconfig",
28+
"freetype",
29+
"fribidi",
30+
"gettext",
31+
"ghostscript",
32+
"giflib",
33+
"git-lfs",
34+
"glib",
35+
"graphite2",
36+
"groff",
37+
"harfbuzz",
38+
"hyperfine",
39+
"icu4c",
40+
"jasper",
41+
"jbig2dec",
42+
"jenv",
43+
"jpeg-turbo",
44+
"jq",
45+
"krb5",
46+
"leptonica",
47+
"libarchive",
48+
"libb2",
49+
"libidn",
50+
"libpaper",
51+
"libpng",
52+
"libpq",
53+
"libtiff",
54+
"libx11",
55+
"libxau",
56+
"libxcb",
57+
"libxdmcp",
58+
"libxext",
59+
"libxfixes",
60+
"libxi",
61+
"libxrender",
62+
"little-cms2",
63+
"lz4",
64+
"lzo",
65+
"mas",
66+
"mpdecimal",
67+
"netpbm",
68+
"oniguruma",
69+
"openjdk@11",
70+
"openjdk@17",
71+
"openjpeg",
72+
"openssl@3",
73+
"packer",
74+
"pango",
75+
"pcre2",
76+
"pgcli",
77+
"pixman",
78+
"postgresql@14",
79+
"psutils",
80+
"python-packaging",
81+
"python@3.12",
82+
"readline",
83+
"softnet",
84+
"sqlite",
85+
"sshpass",
86+
"tart",
87+
"tcl-tk",
88+
"tesseract",
89+
"uchardet",
90+
"webp",
91+
"xorgproto",
92+
"xz",
93+
"zstd"
94+
]
95+
},
96+
{"version":"1.10.5","type":"terraform"},
97+
{ "type": "alias", "alias": "gcdsdd", "value": "git clone" },
98+
{
99+
"type": "ssh-config",
100+
"hosts": [
101+
{
102+
"Host": "192.168.64.94",
103+
"HostName": "192.168.64.94",
104+
"User": "admin"
105+
},
106+
{
107+
"Host": "192.168.2.48",
108+
"HostName": "192.168.2.48",
109+
"User": "pi"
110+
},
111+
{
112+
"Host": "*",
113+
"AddKeysToAgent": "yes",
114+
"IdentityFile": "~/.ssh/id_ed25519"
115+
},
116+
{
117+
"Host": "ec2",
118+
"HostName": "54.82.78.202",
119+
"User": "ec2-user",
120+
"IdentityFile": "~/.ssh/ed25519"
121+
},
122+
{
123+
"Host": "ec2-2",
124+
"HostName": "35.153.180.154",
125+
"User": "ec2-user",
126+
"IdentityFile": "~/.ssh/ed25519"
127+
}
20128
]
21129
},
22-
{ "type": "terraform" },
23-
{ "type": "alias", "alias": "gcdsdd", "value": "git clone" }
130+
{
131+
"type": "ssh-key",
132+
"fileName": "id_ed25519",
133+
"passphrase": "",
134+
"folder": "/Users/kevinwang/.ssh",
135+
"keyType": "ed25519"
136+
},
137+
{
138+
"type": "alias",
139+
"alias": "gcc",
140+
"value": "git commit -v"
141+
},
142+
{
143+
"type": "alias",
144+
"alias": "gc",
145+
"value": "git commit -v"
146+
},
147+
{
148+
"type": "pgcli"
149+
},
150+
{
151+
"type": "aws-cli"
152+
},
153+
{
154+
"type": "vscode",
155+
"directory": "/Applications"
156+
},
157+
{
158+
"type": "xcode-tools"
159+
},
160+
{
161+
"type": "git-clone",
162+
"autoVerifySSH": true,
163+
"directory": "/Users/kevinwang/projects/codify",
164+
"repository": "git@github.com:kevinwang5658/codify.git"
165+
},
166+
{
167+
"type": "git-lfs"
168+
},
169+
{
170+
"type": "pyenv",
171+
"global": "3.11",
172+
"pythonVersions": [
173+
"3.9.19",
174+
"3.10.14",
175+
"3.11.8",
176+
"3.12.2"
177+
]
178+
},
179+
{
180+
"type": "git",
181+
"email": "kevinwang5658@gmail.com",
182+
"username": "kevinwang"
183+
},
184+
{
185+
"type": "android-studio",
186+
"directory": "/Applications",
187+
"version": "2023.3.1.20"
188+
},
189+
{
190+
"type": "nvm",
191+
"global": "20.15.1",
192+
"nodeVersions": [
193+
"iojs-2.5.0",
194+
"18.20.3",
195+
"20.15.0",
196+
"20.15.1",
197+
"22.4.1",
198+
"23.3.0"
199+
]
200+
},
201+
{
202+
"type": "jenv",
203+
"add": [
204+
"system",
205+
"11",
206+
"11.0",
207+
"11.0.24",
208+
"17",
209+
"17.0.12",
210+
"openjdk64-11.0.24",
211+
"openjdk64-17.0.12"
212+
],
213+
"global": "17"
214+
},
215+
{
216+
"type": "aws-profile",
217+
"region": "us-west-2",
218+
"awsAccessKeyId": "AKIATCKATKL55TT5UZ7P",
219+
"awsSecretAccessKey": "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",
220+
"output": "json",
221+
"profile": "codify"
222+
}
24223
]

src/entities/project.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,15 @@ ${JSON.stringify(projectConfigs, null, 2)}`);
123123
return uninstallProject;
124124
}
125125

126-
findResource(type: string, name?: string): ResourceConfig | null {
126+
findAll(type: string, name?: string): ResourceConfig[] {
127+
return this.resourceConfigs.filter((r) =>
128+
name
129+
? r.isSame(type, name)
130+
: r.type === type
131+
);
132+
}
133+
134+
findSpecific(type: string, name?: string): ResourceConfig | null {
127135
return this.resourceConfigs.find((r) => r.isSame(type, name)) ?? null;
128136
}
129137

@@ -157,7 +165,7 @@ ${JSON.stringify(projectConfigs, null, 2)}`);
157165
if (invalidResults.length > 0) {
158166
const resourceErrors: PluginValidationErrorParams = invalidResults.map((r,) => ({
159167
customErrorMessage: r.customValidationErrorMessage,
160-
resource: this.findResource(r.resourceType, r.resourceName)!,
168+
resource: this.findSpecific(r.resourceType, r.resourceName)!,
161169
schemaErrors: r.schemaValidationErrors,
162170
}))
163171

src/entities/resource-info.ts

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { GetResourceInfoResponseData } from 'codify-schemas';
22

3+
import { ResourceConfig } from './resource-config.js';
4+
35
interface ParameterInfo {
46
name: string;
57
type?: string;
@@ -15,6 +17,8 @@ export class ResourceInfo implements GetResourceInfoResponseData {
1517
dependencies?: string[] | undefined;
1618
import?: { requiredParameters: null | string[]; } | undefined;
1719

20+
private parametersCache?: ParameterInfo[];
21+
1822
private constructor() {}
1923

2024
get description(): string | undefined {
@@ -26,31 +30,47 @@ export class ResourceInfo implements GetResourceInfoResponseData {
2630
Object.assign(resourceInfo, data);
2731
return resourceInfo;
2832
}
33+
34+
attachDefaultValues(resource: ResourceConfig): void {
35+
const parameterInfo = this.getParameterInfo();
36+
parameterInfo.forEach((info) => {
37+
const matchedParameter = resource.parameters[info.name];
38+
if (matchedParameter) {
39+
info.value = matchedParameter;
40+
}
41+
})
42+
}
2943

3044
getParameterInfo(): ParameterInfo[] {
31-
const { schema } = this;
32-
if (!schema || !schema.properties) {
33-
return [];
34-
}
45+
if (!this.parametersCache) {
46+
const { schema } = this;
47+
if (!schema || !schema.properties) {
48+
this.parametersCache = [];
49+
return [];
50+
}
51+
52+
const { properties, required } = schema;
53+
if (!properties || typeof properties !== 'object') {
54+
this.parametersCache = [];
55+
return [];
56+
}
57+
58+
this.parametersCache = Object.entries(properties)
59+
.map(([propertyName, info]) => {
60+
const isRequired = this.import?.requiredParameters?.some((name) => name === propertyName)
61+
?? (required as string[] | undefined)?.includes(propertyName)
62+
?? false;
3563

36-
const { properties, required } = schema;
37-
if (!properties || typeof properties !== 'object') {
38-
return [];
64+
return {
65+
name: propertyName,
66+
type: info.type ?? null,
67+
description: info.description,
68+
isRequired
69+
}
70+
});
3971
}
4072

41-
return Object.entries(properties)
42-
.map(([propertyName, info]) => {
43-
const isRequired = this.import?.requiredParameters?.some((name) => name === propertyName)
44-
?? (required as string[] | undefined)?.includes(propertyName)
45-
?? false;
46-
47-
return {
48-
name: propertyName,
49-
type: info.type ?? null,
50-
description: info.description,
51-
isRequired
52-
}
53-
})
73+
return this.parametersCache;
5474
}
5575

5676
getRequiredParameters(): ParameterInfo[] {

src/orchestrators/import.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,9 @@ export class ImportOrchestrator {
6161
await ImportOrchestrator.validate(matchedTypes, project, pluginManager, typeIdsToDependenciesMap);
6262

6363
const resourceInfoList = await pluginManager.getMultipleResourceInfo(matchedTypes);
64-
// Figure out which resources we need to prompt the user for additional info (based on the resource info)
65-
const [noPrompt, askPrompt] = resourceInfoList.reduce((result, info) => {
66-
info.getRequiredParameters().length === 0 ? result[0].push(info) : result[1].push(info);
67-
return result;
68-
}, [<ResourceInfo[]>[], <ResourceInfo[]>[]])
6964

70-
const userSupplied = await reporter.promptUserForValues(askPrompt, PromptType.IMPORT);
71-
72-
const valuesToImport = [
73-
...noPrompt.map((info) => new ResourceConfig({ type: info.type })),
74-
...userSupplied
75-
]
76-
const importResult = await ImportOrchestrator.getImportedConfigs(pluginManager, valuesToImport)
65+
const importParameters = await ImportOrchestrator.getImportParameters(reporter, project, resourceInfoList);
66+
const importResult = await ImportOrchestrator.import(pluginManager, importParameters);
7767

7868
ctx.processFinished(ProcessName.IMPORT)
7969
reporter.displayImportResult(importResult, false);
@@ -84,7 +74,7 @@ export class ImportOrchestrator {
8474
await ImportOrchestrator.saveResults(reporter, importResult, project, resourceInfoList)
8575
}
8676

87-
static async getImportedConfigs(
77+
static async import(
8878
pluginManager: PluginManager,
8979
resources: ResourceConfig[],
9080
): Promise<ImportResult> {
@@ -165,6 +155,28 @@ ${JSON.stringify(unsupportedTypeIds)}`);
165155
ctx.subprocessFinished(SubProcessName.VALIDATE)
166156
}
167157

158+
private static async getImportParameters(reporter: Reporter, project: Project, resourceInfoList: ResourceInfo[]): Promise<Array<ResourceConfig>> {
159+
// Figure out which resources we need to prompt the user for additional info (based on the resource info)
160+
const [noPrompt, askPrompt] = resourceInfoList.reduce((result, info) => {
161+
info.getRequiredParameters().length === 0 ? result[0].push(info) : result[1].push(info);
162+
return result;
163+
}, [<ResourceInfo[]>[], <ResourceInfo[]>[]])
164+
165+
askPrompt.forEach((info) => {
166+
const matchedResources = project.findAll(info.type);
167+
if (matchedResources.length > 0) {
168+
info.attachDefaultValues(matchedResources[0]);
169+
}
170+
})
171+
172+
const userSupplied = await reporter.promptUserForValues(askPrompt, PromptType.IMPORT);
173+
174+
return [
175+
...noPrompt.map((info) => new ResourceConfig({ type: info.type })),
176+
...userSupplied
177+
]
178+
}
179+
168180
private static async saveResults(reporter: Reporter, importResult: ImportResult, project: Project, resourceInfoList: ResourceInfo[]): Promise<void> {
169181
const projectExists = !project.isEmpty();
170182
const multipleCodifyFiles = project.codifyFiles.length > 1;

0 commit comments

Comments
 (0)