Automated codebase updater.
Important
This project a proof of concept in the current state.
Manually applying a change across multiple repositotires can become tiresome.
Codeup exposes conventional utils and a CLI to make it easier to migrate code and apply changes automatically and programmatically.
You can define shared actions using codeup. See ./actions dir for some examples.
import { defineAction } from "codeup";
export default defineAction({
meta: {
name: "",
description: "",
date: "",
},
async filter({ utils, logger }) {},
async apply({ utils, logger }) {},
});
Example:
import { defineAction } from "codeup";
export default defineAction({
meta: {
name: "eslint-flat",
description: "Upgrade to eslint flat config with unjs preset",
date: "2024-05-03",
},
async filter({ utils }) {
// Only apply if legacy eslint config is found
return (
(await utils.existsWithAnyExt(".eslintrc")) &&
!(await utils.existsWithAnyExt("eslint.config"))
);
},
async apply({ utils }) {
// Migrate to new eslint config
const eslintRC = await utils.readJSON(".eslintrc");
const eslintignore = (await utils.readLines(".eslintignore")) || [];
await utils.write(
"eslint.config.mjs",
getConfigTemplate({
rules: eslintRC?.rules || {},
ignores: eslintignore.filter(
(i) => !["", "node_modules", "dist", "coverage"].includes(i),
),
}),
);
// Remove legacy eslint config files
await utils.remove(".eslintrc");
await utils.remove(".eslintignore");
// Update package.json scripts
await utils.updatePackageJSON((pkg) => {
if (!pkg.scripts) {
return;
}
for (const name in pkg.scripts) {
if (pkg.scripts[name].includes("eslint")) {
pkg.scripts[name] = pkg.scripts[name].replace(/--ext\s+\S+\s/, "");
}
}
});
// Ensure latest eslint and preset versions are installed
await utils.addDevDependency([
"eslint@^9.0.0",
"eslint-config-unjs@^0.3.0",
]);
// Run lint:fix script once
await utils.runScript("lint:fix");
},
});
function getConfigTemplate(opts: {
rules: Record<string, unknown>;
ignores: string[];
}) {
return /* js */ `
import unjs from "eslint-config-unjs";
// https://github.com/unjs/eslint-config
export default unjs({
ignores: ${JSON.stringify(opts.ignores || [], undefined, 2)},
rules: ${JSON.stringify(opts.rules || {}, undefined, 2)},
});
`.trim();
}
You can use codeup apply
CLI to apply actions from a local directory or remote source (powered by unjs/giget).
By default actions order will be sorted by date and name.
# Run all actions from local dir
npx codeup apply --actions path/to/actions/dir
# Run actions from a github source
npx codeup apply --actions gh:unjs/codeup/actions/unjs
You can directly use codeup utils as a library use use them within actions context.
import { readJSON, runScript } from "codeup/utils";
Append text to a file (with a newline by default)
Checks if a file or directory exists in path
Checks if a file or directory exists in path with any extension (input path should not contain extension)
Try to find a file in the current working directory or any parent directories
Try to read a text file and returns its contents
Read a text file and return its contents as an array of lines
Try to remove a file or directory
Resolves a path relative to the current working directory.
Read a file and update its contents
Returns the updated contents or the old one
Write text contents to a file
Try to read a JSON file
Try to update a JSON file using an updater function and return updated JSON
Write a JSON file
Add a dependency to the project using detected package manager
Add a dev dependency to the project using detected package manager
Try to read the closest package.json file
Remove a dependency from the project using detected package manager
Run a package.json
script using detected package manager
Try to update the closest package.json file
You can integrate codeup in your workflows using programmatic API instead of CLI.
import { applyActionsFrom } from "codeup";
Apply an action within context and working directory.
Load and apply action from file.
Apply multiple actions within context and working directory.
If opts.sort
is true, actions will be sorted by date or name otherwise in the order they are provided.
Load and apply actions from a remote or local source.
Load and apply actions from directory.
Create an action context from a working directory.
Get action name from action object.
Load action from file.
Load actions from a directory.
Run a function within a context.
Sort actions by date or name.
Get the current action context or create a new one from the working directory.
local development
Published under the MIT license.
Made by @pi0 and community 💛
🤖 auto updated with automd