@softwareventures/maintain-project
Version:
Automatically create and maintain TypeScript projects with standard settings for Software Ventures Limited
99 lines • 4.91 kB
JavaScript
import { simpleGit } from "simple-git";
import { concat, map } from "@softwareventures/array";
import wrap from "wordwrap";
import { bindAsyncResultFn, failure, mapAsyncResultFn, mapResultFn, success, throwFailureFn, tolerantFoldAsyncResultsFn } from "../result/result.js";
import { emptyDirectory } from "../fs-stage/directory.js";
import { updateCopyrightYear } from "../license/update-copyright-year.js";
import { commit } from "../fs-stage/commit.js";
import { addMissingLicense } from "../license/add-missing-license.js";
import { applyCodeStyle } from "../yarn/apply-code-style.js";
import { prettierFixFilesIfAvailable } from "../prettier/fix.js";
import { updateFixScript } from "../npm/update-fix-script.js";
import { updateLintScript } from "../npm/update-lint-script.js";
import { addNewNodeVersionsToPackageJson } from "../npm/add-new-node-versions.js";
import { addMissingNodeVersionsToGitHubActions } from "../github/add-missing-node-versions.js";
import { applyCodeStyleToPackageJson } from "../npm/apply-code-style.js";
import { useLatestNodeToDeploy } from "../github/use-latest-node-to-deploy.js";
import { useLatestNodeToMaintain } from "../github/use-latest-node-to-maintain.js";
import { dropOldNodeVersions } from "../node/drop-old-versions.js";
import { removeUnsupportedNodeVersions } from "../github/remove-unsupported-node-versions.js";
import { removeTslintFromTestScript } from "../npm/remove-tslint-from-test-script.js";
import { addYarnLintToCiWorkflow } from "../github/add-yarn-lint-to-ci-workflow.js";
import { addMissingIdeaRunConfigurations } from "../idea/add-missing-run-configurations.js";
import { enableDisableIdeaTslintInspection } from "../idea/enable-disable-tslint.js";
import { enableDisableIdeaEslintInspection } from "../idea/enable-disable-eslint.js";
export async function updateProject(options) {
const git = simpleGit(options.project.path);
return Promise.resolve([
applyCodeStyleToPackageJson,
updateLintScript,
updateFixScript,
addYarnLintToCiWorkflow,
removeTslintFromTestScript,
enableDisableIdeaTslintInspection,
enableDisableIdeaEslintInspection,
applyCodeStyle,
updateCopyrightYear,
addMissingLicense,
removeUnsupportedNodeVersions,
dropOldNodeVersions,
addNewNodeVersionsToPackageJson,
addMissingNodeVersionsToGitHubActions,
useLatestNodeToDeploy,
useLatestNodeToMaintain,
addMissingIdeaRunConfigurations
]).then(tolerantFoldAsyncResultsFn(async (project, update) => step({ ...options, project, git, update }), options.project));
}
export function gitNotClean(path) {
return { type: "git-not-clean", path };
}
async function step({ project, breaking, git, update }) {
return git
.status()
.then(status => (status.isClean() ? success() : failure([gitNotClean(project.path)])))
.then(mapAsyncResultFn(async () => update(project)))
.then(mapAsyncResultFn(async (update) => (breaking ?? false) || (update?.breaking?.length ?? 0) === 0 ? update : null))
.then(bindAsyncResultFn(async (update) => commitUpdate(project, git, update)));
}
async function commitUpdate(project, git, update) {
if (update == null) {
return success(project);
}
return writeUpdate(project, update)
.then(mapAsyncResultFn(async () => git.status()))
.then(mapResultFn(status => concat([status.modified, status.not_added])))
.then(bindAsyncResultFn(async (files) => prettierFixFilesIfAvailable(project, files).then(() => success(files)) // Ignore failure
))
.then(mapAsyncResultFn(async () => git.status()))
.then(mapResultFn(status => concat([status.modified, status.not_added])))
.then(mapAsyncResultFn(async (files) => files.length === 0
? undefined
: git
.add(files)
.then(async () => git.commit(generateCommitLog(update), { "--no-verify": null }))))
.then(mapResultFn(commitResult => {
if (commitResult != null && commitResult.commit !== "") {
console.log(`Applied update: ${update.log}`);
return update.updatedProject ?? project;
}
else {
return project;
}
}));
}
function generateCommitLog(update) {
return (update.log +
map(update.breaking ?? [], breaking => wrap(62)(`\n\nBREAKING CHANGE: ${breaking}`)).join(""));
}
async function writeUpdate(project, update) {
switch (update.type) {
case "fs-stage-update":
return update
.apply({ root: emptyDirectory, overwrite: true })
.then(throwFailureFn("Internal error creating update file stage"))
.then(async (stage) => commit(project.path, stage));
case "direct-update":
return update.apply();
}
}
//# sourceMappingURL=update.js.map