Skip to content

Commit

Permalink
integrity checking and dependency resolution now
Browse files Browse the repository at this point in the history
account for templates having indirect references to includes -
addresses issue #82
  • Loading branch information
jeffschwartz committed Aug 6, 2019
1 parent c45de85 commit e97feec
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 13 deletions.
14 changes: 13 additions & 1 deletion lib/buildanalyzer/integrityCheck/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
getAllIncludes,
getCachedMatter,
getTagCallbackDependencies,
resolveIndirectPathToInclude,
mdToHtml,
readCache,
toArray
Expand All @@ -18,6 +19,8 @@ module.exports = (assets) => {
const missingAssets = [];
const noteMissingAsset = path =>
!existsSync(path) && missingAssets.push(path);
const noteMissingIndirectInclude = (templatePath, name) =>
missingAssets.push(`${name}, indirectly referenced in ${templatePath}`);

// check each fragment for missing assets
assets.filter(path => path.startsWith(config.fragments))
Expand Down Expand Up @@ -48,7 +51,16 @@ module.exports = (assets) => {
// check for missing include dependencies
const includes = getAllIncludes($content);
includes && includes.length > 0 && includes.forEach(include => {
noteMissingAsset(`${config.includes}${sep}${include}`);
if (parse(include).ext === "") {
// include is referenced indirectly so search fragments
// for matching variable and use its value instead
// *note: it is possible that the template is not referenced by any fragment so ignore it then
const includePath = resolveIndirectPathToInclude(path, include,
assets.filter(path => path.startsWith(config.fragments)));
!includePath && noteMissingIndirectInclude(path, include);
} else {
noteMissingAsset(`${config.includes}${sep}${include}`);
}
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ const {
} = require("../../../utils");

module.exports = (resolvedFragmentPath, pathsToAllTemplates, pathsToAllIncludes) => {
const fragmentMatter = getCachedMatter(resolvedFragmentPath);
let includeBaseNames =
getAllIncludes(cheerio.load(mdToHtml(resolvedFragmentPath, readCache(resolvedFragmentPath))));
const templateBaseName = getCachedMatter(resolvedFragmentPath).data.template;
const templateBaseName = fragmentMatter.data.template;
const templatePath = pathsToAllTemplates.find(path => parse(path).base === templateBaseName);
includeBaseNames = includeBaseNames.concat(getAllIncludes(cheerio.load(readCache(templatePath))));
includeBaseNames = includeBaseNames.concat(getAllIncludes(cheerio.load(readCache(templatePath)))
.map(name => parse(name).ext !== "" ? name : fragmentMatter.data[name]));
return pathsToAllIncludes.filter(path => includeBaseNames.includes(parse(path).base));
};
30 changes: 21 additions & 9 deletions lib/buildanalyzer/resolveDependencies/resolvers/getIncludeDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,37 @@ const {
getAllIncludes,
getCachedMatter,
mdToHtml,
readCache
readCache,
resolveIndirectPathToInclude
} = require("../../../utils");

module.exports = (includeStat, pathsToAllTemplates, pathsToAllFrags) => {
includeStat.templateDeps = pathsToAllTemplates
.filter(path =>
// checks if template references include in its content
getAllIncludes(cheerio.load(readCache(path)))
.includes(parse(includeStat.path).base));
includeStat.templateDeps = pathsToAllTemplates.filter(path => {
const base = parse(includeStat.path).base;
const includes = getAllIncludes(cheerio.load(readCache(path)));
// check if template directly references include in its content
const condition1 = () =>
includes.includes(base);
// check if template indirectly references include in its content
const condition2 = () => {
const indirectNames = includes.filter(include => parse(include).ext === "");
return indirectNames.some(indirectName => {
const resolved = resolveIndirectPathToInclude(path, indirectName, pathsToAllFrags);
return resolved === base;
});
};
return condition1() || condition2();
});
includeStat.fragDeps = pathsToAllFrags
.filter(path => {
const m = getCachedMatter(path);
// checks if fragments is associated with template
// via its front matter that references include
const condition1 = () =>
// checks if fragments is associated with template
// via its front matter that references include
includeStat.templateDeps
.some(template => parse(template).base === m.data.template);
// checks if fragment references include in its content
const condition2 = () =>
// checks if fragment references include in its content
getAllIncludes(cheerio.load(mdToHtml(path, m.content)))
.includes(parse(includeStat.path).base);
return condition1() || condition2();
Expand Down
3 changes: 2 additions & 1 deletion lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ module.exports = {
globFriendly: require("./globFriendly"),
getTagCallbacks: require("./getTagCallbacks"),
getTagCallbackDependencies: require("./getTagCallbackDependencies"),
isFile: require("./isFile")
isFile: require("./isFile"),
resolveIndirectPathToInclude: require("./resolveIndirectPathToInclude")
};
15 changes: 15 additions & 0 deletions lib/utils/resolveIndirectPathToInclude.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { parse } = require("path");
const getCachedMatter = require("./getCachedMatter");

module.exports = (templatePath, dataKey, pathsToFragments) => {
// find the fragment associated with the template
const fragmentPath = pathsToFragments.find(fragmentPath =>
getCachedMatter(fragmentPath).data.template === parse(templatePath).base);
// if found then return the property value for dataKey - will
// return undefined if fragment wasn't found (not implemented yet) or
// if found fragment's matter.data doesn't have a key by that name
if (fragmentPath) {
const fragmentMatter = getCachedMatter(fragmentPath);
return fragmentMatter.data[dataKey];
}
};

0 comments on commit e97feec

Please sign in to comment.