Skip to content

Commit 651c9ab

Browse files
committed
pull additional files from github and improve recipe list UI
1 parent 236f399 commit 651c9ab

File tree

6 files changed

+283
-147
lines changed

6 files changed

+283
-147
lines changed

app/page.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
DocumentTextIcon,
99
ExclamationCircleIcon
1010
} from "@heroicons/react/24/outline";
11-
import { ContainerRecipe } from "@/components/common";
11+
import { ContainerRecipe, migrateLegacyRecipe } from "@/components/common";
1212
import BuildRecipeComponent from "@/components/recipe";
1313
import ContainerMetadata from "@/components/metadata";
1414
import ValidateRecipeComponent from "@/components/validate";
@@ -577,7 +577,8 @@ export default function Home() {
577577
reader.onload = (event) => {
578578
const text = event.target?.result as string;
579579
try {
580-
const parsed = loadYAML(text) as ContainerRecipe;
580+
let parsed = loadYAML(text) as ContainerRecipe;
581+
parsed = migrateLegacyRecipe(parsed);
581582
setYamlData(parsed);
582583
} catch (err) {
583584
console.error("Error parsing YAML:", err);
@@ -597,7 +598,8 @@ export default function Home() {
597598
reader.onload = (event) => {
598599
const text = event.target?.result as string;
599600
try {
600-
const parsed = loadYAML(text) as ContainerRecipe;
601+
let parsed = loadYAML(text) as ContainerRecipe;
602+
parsed = migrateLegacyRecipe(parsed);
601603
setYamlData(parsed);
602604
} catch (err) {
603605
console.error("Error parsing YAML:", err);

components/common.ts

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export interface TestDirective extends BaseDirective {
9595

9696
export const IncludeMacros = ["macros/openrecon/neurodocker.yaml"] as const;
9797

98-
export type IncludeMacro = typeof IncludeMacros[number];
98+
export type IncludeMacro = (typeof IncludeMacros)[number];
9999

100100
export interface IncludeDirective extends BaseDirective {
101101
include: IncludeMacro;
@@ -136,4 +136,81 @@ export interface ContainerRecipe {
136136
files?: FileInfo[];
137137
deploy?: DeployInfo;
138138
tests?: TestInfo[];
139+
}
140+
141+
export function migrateLegacyRecipe(
142+
recipe: ContainerRecipe
143+
): ContainerRecipe {
144+
const directives: Directive[] = [];
145+
146+
// Migrate files to file directives
147+
if (recipe.files?.length) {
148+
directives.push(
149+
...recipe.files.map(
150+
(file): FileDirective => ({
151+
file,
152+
})
153+
)
154+
);
155+
}
156+
157+
// Migrate deploy to deploy directive
158+
if (recipe.deploy) {
159+
directives.push({
160+
deploy: recipe.deploy,
161+
});
162+
}
163+
164+
// Migrate tests to test directives
165+
if (recipe.tests?.length) {
166+
directives.push(
167+
...recipe.tests.map(
168+
(test): TestDirective => ({
169+
test,
170+
})
171+
)
172+
);
173+
}
174+
175+
const ret = {
176+
...recipe,
177+
build: {
178+
...recipe.build,
179+
directives: [...directives, ...recipe.build.directives],
180+
},
181+
};
182+
delete ret.files;
183+
delete ret.deploy;
184+
delete ret.tests;
185+
return ret;
186+
}
187+
188+
export async function mergeAdditionalFilesIntoRecipe(recipe: ContainerRecipe, fetchFile: (filename: string) => Promise<string>): Promise<ContainerRecipe> {
189+
// Look for file directives in the recipe. Make sure to handle group directives.
190+
// For each file directive if they have a filename then download it and replace the filename with the contents.
191+
const processDirective = async (directive: Directive): Promise<Directive> => {
192+
if ('file' in directive) {
193+
const file = directive.file;
194+
if (file.filename) {
195+
try {
196+
file.contents = await fetchFile(file.filename);
197+
delete file.filename; // Remove filename after fetching
198+
} catch (error) {
199+
console.error(`Failed to fetch file ${file.filename}:`, error);
200+
}
201+
}
202+
} else if ('group' in directive) {
203+
directive.group = await Promise.all(directive.group.map(processDirective));
204+
}
205+
return directive;
206+
}
207+
208+
const directives = await Promise.all(recipe.build.directives.map(processDirective));
209+
return {
210+
...recipe,
211+
build: {
212+
...recipe.build,
213+
directives: directives,
214+
},
215+
};
139216
}

components/directives/install.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ export default function InstallDirectiveComponent({
1717
if (typeof install === "string") {
1818
setPackages(install.split(/\s+/).filter((pkg) => pkg.trim() !== ""));
1919
} else if (Array.isArray(install)) {
20-
setPackages(install.filter((pkg) => pkg.trim() !== ""));
20+
// each array element can contain multiple packages
21+
const allPackages = install.flatMap((pkg) => pkg.split(/\s+/).filter((p) => p.trim() !== ""));
22+
setPackages(allPackages);
2123
} else {
2224
setPackages([]);
2325
}

0 commit comments

Comments
 (0)