Skip to content

Commit a9b7d7a

Browse files
committed
project - maintain render list order
1 parent 3ab981d commit a9b7d7a

File tree

1 file changed

+75
-60
lines changed

1 file changed

+75
-60
lines changed

src/project/project-context.ts

Lines changed: 75 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,6 @@ export async function projectInputFiles(
724724
metadata?: ProjectConfig,
725725
): Promise<{ files: string[]; engines: string[] }> {
726726
const { dir } = project;
727-
const files: string[] = [];
728-
const engines: string[] = [];
729-
const intermediateFiles: string[] = [];
730727

731728
const outputDir = metadata?.project[kProjectOutputDir];
732729

@@ -738,84 +735,102 @@ export async function projectInputFiles(
738735
globToRegExp(glob, { extended: true, globstar: true })
739736
);
740737

741-
const addFile = async (file: string) => {
738+
type FileInclusion = {
739+
file: string;
740+
engineName: string;
741+
engineIntermediates: string[];
742+
};
743+
744+
const addFile = async (file: string): Promise<FileInclusion | undefined> => {
745+
// ignore the file if it is in the output directory
742746
if (
743-
// no output dir to worry about
744-
!outputDir ||
745-
// crawled file is not inside the output directory
746-
!ensureTrailingSlash(dirname(file)).startsWith(
747+
outputDir &&
748+
ensureTrailingSlash(dirname(file)).startsWith(
747749
ensureTrailingSlash(join(dir, outputDir)),
748-
) ||
749-
// output directory is not in the project directory
750-
// so we don't need to worry about crawling outputs
751-
!ensureTrailingSlash(join(dir, outputDir)).startsWith(
750+
) &&
751+
ensureTrailingSlash(join(dir, outputDir)).startsWith(
752752
ensureTrailingSlash(dir),
753753
)
754754
) {
755-
const engine = await fileExecutionEngine(file, undefined, project);
756-
if (engine) {
757-
if (!engines.includes(engine.name)) {
758-
engines.push(engine.name);
759-
}
760-
files.push(file);
761-
const engineIntermediates = executionEngineIntermediateFiles(
762-
engine,
763-
file,
764-
);
765-
if (engineIntermediates) {
766-
intermediateFiles.push(...engineIntermediates);
767-
}
768-
}
755+
return;
769756
}
770-
};
771757

772-
const addDir = async (dir: string) => {
758+
const engine = await fileExecutionEngine(file, undefined, project);
759+
// ignore the file if there's no engine to handle it
760+
if (!engine) {
761+
return undefined;
762+
}
763+
const engineIntermediates = executionEngineIntermediateFiles(
764+
engine,
765+
file,
766+
);
767+
return {
768+
file,
769+
engineName: engine.name,
770+
engineIntermediates: engineIntermediates,
771+
};
772+
};
773+
const addDir = async (dir: string): Promise<FileInclusion[]> => {
773774
// ignore selected other globs
774-
775-
for (
776-
const walk of walkSync(
777-
dir,
778-
{
779-
includeDirs: false,
780-
// this was done b/c some directories e.g. renv/packrat and potentially python
781-
// virtualenvs include symblinks to R or Python libraries that are in turn
782-
// circular. much safer to not follow symlinks!
783-
followSymlinks: false,
784-
skip: [kSkipHidden].concat(
785-
engineIgnoreDirs().map((ignore) =>
786-
globToRegExp(join(dir, ignore) + SEP)
787-
),
775+
const walkIterator = walkSync(
776+
dir,
777+
{
778+
includeDirs: false,
779+
// this was done b/c some directories e.g. renv/packrat and potentially python
780+
// virtualenvs include symblinks to R or Python libraries that are in turn
781+
// circular. much safer to not follow symlinks!
782+
followSymlinks: false,
783+
skip: [kSkipHidden].concat(
784+
engineIgnoreDirs().map((ignore) =>
785+
globToRegExp(join(dir, ignore) + SEP)
788786
),
789-
},
790-
)
791-
) {
792-
const pathRelative = pathWithForwardSlashes(relative(dir, walk.path));
793-
if (!projectIgnores.some((regex) => regex.test(pathRelative))) {
794-
await addFile(walk.path);
787+
),
788+
},
789+
);
790+
return Promise.all(
791+
Array.from(walkIterator)
792+
.filter((walk) => {
793+
const pathRelative = pathWithForwardSlashes(relative(dir, walk.path));
794+
return !projectIgnores.some((regex) => regex.test(pathRelative));
795+
})
796+
.map(async (walk) => addFile(walk.path)),
797+
).then((fileInclusions) => fileInclusions.filter((f) => f !== undefined));
798+
};
799+
const addEntry = async (entry: string) => {
800+
if (Deno.statSync(entry).isDirectory) {
801+
return addDir(entry);
802+
} else {
803+
const inclusion = await addFile(entry);
804+
if (inclusion) {
805+
return [inclusion];
806+
} else {
807+
return [];
795808
}
796809
}
797810
};
798-
799811
const renderFiles = metadata?.project[kProjectRender];
812+
813+
let inclusions: FileInclusion[];
800814
if (renderFiles) {
801815
const exclude = projIgnoreGlobs.concat(outputDir ? [outputDir] : []);
802816
const resolved = resolvePathGlobs(dir, renderFiles, exclude, {
803817
mode: "auto",
804818
});
805-
await Promise.all(
806-
(ld.difference(resolved.include, resolved.exclude) as string[])
807-
.map((file) => {
808-
if (Deno.statSync(file).isDirectory) {
809-
return addDir(file);
810-
} else {
811-
return addFile(file);
812-
}
813-
}),
814-
);
819+
const toInclude = ld.difference(
820+
resolved.include,
821+
resolved.exclude,
822+
) as string[];
823+
inclusions = (await Promise.all(toInclude.map(addEntry))).flat();
815824
} else {
816-
await addDir(dir);
825+
inclusions = await addDir(dir);
817826
}
818827

828+
const files = inclusions.map((inclusion) => inclusion.file);
829+
const engines = ld.uniq(inclusions.map((inclusion) => inclusion.engineName));
830+
const intermediateFiles = inclusions.map((inclusion) =>
831+
inclusion.engineIntermediates
832+
).flat();
833+
819834
const inputFiles = ld.difference(
820835
ld.uniq(files),
821836
ld.uniq(intermediateFiles),

0 commit comments

Comments
 (0)