declapract
Version:
A tool to declaratively define best practices, maintainable evolve them, and scalably enforce them.
86 lines • 5.88 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.readUsePracticesConfig = void 0;
const find_nearest_package_json_1 = require("find-nearest-package-json");
const fs_1 = require("fs");
const ActionUsePracticesConfig_1 = require("../../domain/objects/ActionUsePracticesConfig");
const ActionUsePracticesConfigInput_1 = require("../../domain/objects/ActionUsePracticesConfigInput");
const doesDirectoryExist_1 = require("../../utils/fileio/doesDirectoryExist");
const doesFileExist_1 = require("../../utils/fileio/doesFileExist");
const readYmlFile_1 = require("../../utils/fileio/readYmlFile");
const getDirOfPath_1 = require("../../utils/filepaths/getDirOfPath");
const withDurationReporting_1 = require("../../utils/wrappers/withDurationReporting");
const UserInputError_1 = require("../UserInputError");
const readDeclarePracticesConfig_1 = require("../declaration/readDeclarePracticesConfig");
exports.readUsePracticesConfig = (0, withDurationReporting_1.withDurationReporting)('readUsePracticesConfig', async ({ configPath, }) => {
const configDir = (0, getDirOfPath_1.getDirOfPath)(configPath);
const getAbsolutePathFromRelativeToConfigPath = (relpath) => `${configDir}/${relpath}`;
// get the yml
const contents = await (async () => {
try {
return await (0, readYmlFile_1.readYmlFile)({ filePath: configPath });
}
catch (error) {
throw new UserInputError_1.UserInputError(`could not read config. ${error.message}. See '${configPath}'`);
}
})();
// validate it into an input object
const configInput = new ActionUsePracticesConfigInput_1.ActionUsePracticesConfigInput(contents); // applies runtime validation
// lookup the declared practices using the path specified
const declaredPractices = await (async () => {
// support npm module loading of declarations
if (configInput.declarations.startsWith('npm:')) {
// package name
const packageName = configInput.declarations.slice('npm:'.length);
// if it starts with npm, then make sure that it is installed in package.json
const { data: packageJsonContents } = await (0, find_nearest_package_json_1.findNearestPackageJson)(configDir); // nearest to the config
if (!(packageJsonContents.devDependencies ?? {})[packageName])
throw new UserInputError_1.UserInputError(`specified declarations in npm module, but module is not specified as a devDependency: '${configInput.declarations}'`, {
potentialSolution: `try installing the module, for example: 'npm install --save-dev ${packageName}'`,
});
// now check that it is actually in node_modules dir
const expectedDirectoryRelativePath = `node_modules/${packageName}`;
const directoryExists = await (0, doesDirectoryExist_1.doesDirectoryExist)({
directory: getAbsolutePathFromRelativeToConfigPath(expectedDirectoryRelativePath),
});
if (!directoryExists)
throw new UserInputError_1.UserInputError(`declarations module not found in the node_modules directory: '${packageName}' (checked '${expectedDirectoryRelativePath}')`, {
potentialSolution: "make sure you've ran npm install in this project already. e.g., 'npm install'",
});
// now check that the file exists in the expected spot in that module
const expectedDeclarationsConfigRelativeFilePath = `${expectedDirectoryRelativePath}/declapract.declare.yml`;
const declarationsConfigFileExists = await (0, doesFileExist_1.doesFileExist)({
filePath: getAbsolutePathFromRelativeToConfigPath(expectedDeclarationsConfigRelativeFilePath),
});
if (!declarationsConfigFileExists)
throw new UserInputError_1.UserInputError(`declarations module was found in node_modules directory, but it does not have a 'declapract.declare.yml' file inside of it: '${expectedDeclarationsConfigRelativeFilePath}'`);
// now read declarations from that file
return (0, readDeclarePracticesConfig_1.readDeclarePracticesConfig)({
configPath: getAbsolutePathFromRelativeToConfigPath(expectedDeclarationsConfigRelativeFilePath),
});
}
// support specifying a relative path
const specifiedPath = getAbsolutePathFromRelativeToConfigPath(configInput.declarations);
const specifiedPathStat = await fs_1.promises.lstat(specifiedPath);
const path = specifiedPathStat.isDirectory()
? `${specifiedPath}/declapract.declare.yml`
: specifiedPath; // if the `declarations` path is a directory, assume that the config file has the default name; otherwise, assume that they specified the whole name
if (!path.endsWith('.yml'))
throw new UserInputError_1.UserInputError(`path to declarations must reference a yml file or a directory that has a 'declapract.declare.yml' file. found '${path}' instead`);
const pathStat = await fs_1.promises.lstat(path);
if (!pathStat.isFile())
throw new UserInputError_1.UserInputError(`path to declarations does not reference a real file. '${path}' does not exist`);
return (0, readDeclarePracticesConfig_1.readDeclarePracticesConfig)({ configPath: path });
})();
// return the config
return new ActionUsePracticesConfig_1.ActionUsePracticesConfig({
rootDir: configDir,
declared: declaredPractices,
scope: {
usecase: configInput.scope?.usecase ?? configInput.useCase ?? null,
practices: configInput.scope?.practices,
},
variables: configInput.variables ?? {},
});
});
//# sourceMappingURL=readUsePracticesConfig.js.map