Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Regex can now be applied to any file #22

Merged
merged 5 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions .editorconfig

This file was deleted.

23 changes: 16 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
This projects allows to perform automatically tasks required at release time
like for example:

- Creating a new tag based on existing ones
- Updating versions number in a file, according to the new tag.
- Updating version numbers in the readme, according to the new tag.
- Updating links in readme.
- Creating a changelog.
- Creating a new tag based on existing ones
- Pushing a release to github.

Most changes are optionals and configurable.
Expand Down Expand Up @@ -75,11 +75,20 @@ enabled. To enable them, either
"github": {
"release": true
},
"regex": {
"patterns": [
"(?<=@)(.*)(?=\/cli)"
]
},
"regex": [
{
"file": "README.md",
"patterns": [
"(?<=@)(.*)(?=\/cli)"
]
},
{
"file": "deno.json",
"patterns": [
"(?<=version=\")(.*)\n"
]
}
],
"versionFile": {},
"myRemotePlugin": {
"path": "./plugins/testRemote/mod.ts"
Expand Down
30 changes: 23 additions & 7 deletions cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import changelog from "./plugins/changelog/mod.ts";
import regex from "./plugins/regex/mod.ts";
import versionFile from "./plugins/versionFile/mod.ts";

import version from "./version.json" assert { type: "json" };
import config from "./deno.json" with { type: "json" };
import { ReleasePlugin } from "./plugin.ts";
import { initLogger } from "./src/log.ts";

const version = config.version;

export type ReleaseType =
| "patch"
| "minor"
Expand All @@ -39,7 +41,7 @@ const DEFAULT_CONFIG_PATH = ".release_up.json";

await new Command()
.name("release_up")
.version(version.version)
.version(version)
.description(`
Automate semver releases.
Example: release_up major --github
Expand All @@ -54,15 +56,15 @@ await new Command()
* prerelease <name> ${colors.dim("eg: 1.2.3-name.0 -> 1.2.3-name.1")}`)
.type("semver", new EnumType(release_type))
.arguments("<release_type:semver> [name:string]")
.option("--config <confi_path>", "Define the path of the config.", {
.option("--config <config_path>", "Define the path of the config.", {
default: `${DEFAULT_CONFIG_PATH}`,
})
.option("--github", "Enable Github plugin.")
.option("--changelog", "Enable Changelog plugin.")
.option("--versionFile", "Enable VersionFile plugin.")
.option(
"--regex <pattern:string>",
"Enable Regex plugin. The regex need to be provided as string. --regex can be specified multiple times",
"--regex <file_and_pattern:string>",
"Enable the Regex plugin. The regex argument is of format filepath:::regex eg: --regex 'README.md:::(?<=@)(.*)(?=\/cli)'. --regex can be specified multiple times.",
{ collect: true },
)
.option("--dry", "Dry run, Does not commit any changes.")
Expand Down Expand Up @@ -108,8 +110,23 @@ await new Command()
if (opts.changelog) pluginsList.changelog = changelog;
if (opts.regex) {
pluginsList.regex = regex;
const regs = opts.regex?.map((s) => {
const cf = s.split(":::");
if (cf.length === 1) {
// assume it is readme
return {
file: "README.md",
patterns: [cf[0]],
};
} else {
return {
file: cf[0],
patterns: [cf[1]],
};
}
});
// deno-lint-ignore no-explicit-any
(config as any).regex = { patterns: opts.regex };
(config as any).regex = regs;
}
if (opts.versionFile) pluginsList.versionFile = versionFile;

Expand All @@ -123,7 +140,6 @@ await new Command()
else if (key === "versionFile" && !pluginsList.versionFile) {
pluginsList.versionFile = versionFile;
} else {
console.log(key, val);
const def = val as { path: string };
if (!def.path) throw Error(`Invalid config entry ${key}, ${val}`);
const remotePlugin = await import(def.path);
Expand Down
7 changes: 5 additions & 2 deletions deno.jsonc → deno.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"name": "@sylc/release_up",
"version": "0.7.0",
"exports": "./cli.ts",
"tasks": {
"dev": "deno run -A ./cli.ts --dry --allowUncommitted --regex \"(?<=@)(.*)(?=\/cli)\" --regex \"(?<=Version: )(.*)\n\" --changelog --github",
"release": "deno fmt --check && deno lint && deno run -A ./cli.ts --regex \"(?<=@)(.*)(?=\/cli)\" --regex \"(?<=Version: )(.*)\n\" --github --versionFile --changelog",
"dev": "deno run -A ./cli.ts --dry --allowUncommitted --regex '(?<=@)(.*)(?=\/cli)' --regex '(?<=Version: )(.*)\n' --changelog --github",
"release": "deno fmt --check && deno lint && deno run -A ./cli.ts --config ./tools/.release_up.json",
"test": "deno test -A",
"check": "deno fmt && deno lint"
},
Expand Down
4 changes: 2 additions & 2 deletions doc/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ interface GithubConfig {

# Regex

Apply a regex on the `README.md`. The regex can be configure in the config file.
e.g:
Apply a regex on the `README.md` or any other files with the new version or any
other value. The regex can be configured in the config file. e.g:

```json
"regex": {
Expand Down
56 changes: 44 additions & 12 deletions plugins/regex/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { join } from "./deps.ts";

interface RegexConfig {
regex: {
patterns: string[];
};
file: string;
patterns: string;
}[] | { patterns: string };
}

const plugin: ReleasePlugin<RegexConfig> = {
Expand All @@ -17,17 +18,48 @@ const plugin: ReleasePlugin<RegexConfig> = {
config,
log,
): Promise<void> {
const readmePath = "README.md";
let text = await Deno.readTextFile(readmePath);
// apply regex. This should come from a config loaded on setup step
// as a prototype, it is harcoded to update versions in urls
for (const pattern of config.regex.patterns) {
text = text.replace(new RegExp(pattern), to);
// the below allow for future expansion to change more files
const changeDefs = [];
if (!Array.isArray(config.regex) && config.regex.patterns.length) {
changeDefs.push({
filePath: "README.md",
transforms: [
{ value: to, patterns: config.regex.patterns || [] },
],
});
}
if (config.options.dry) {
log.info(text);
} else {
await Deno.writeTextFile(join(repo.path, readmePath), text);
if (Array.isArray(config.regex)) {
config.regex.forEach((p) => {
changeDefs.push({
filePath: p.file,
transforms: [
{ value: to, patterns: p.patterns },
],
});
});
}

// aggregate all patterns per file
const t = Object.groupBy(changeDefs, ({ filePath }) => filePath);

for (const [filePath, changeDefsForFile] of Object.entries(t)) {
log.info(`processing: ${filePath}`);

let text = await Deno.readTextFile(filePath);
// apply regex.
for (const changeDef of changeDefsForFile!) {
for (const transforms of changeDef.transforms) {
for (const pattern of transforms.patterns) {
log.debug(`regex: ${new RegExp(pattern)}`);
text = text.replace(new RegExp(pattern), transforms.value);
}
}
}
if (config.options.dry) {
log.info(text);
} else {
await Deno.writeTextFile(join(repo.path, filePath), text);
}
}
},
};
Expand Down
31 changes: 15 additions & 16 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,30 @@ import { ReleaseError } from "./error.ts";

const decoder = new TextDecoder();

export async function git(
export function git(
repo: string,
args: string[] | string,
): Promise<[Deno.ProcessStatus, string, string]> {
): [boolean, string, string] {
const dir = `--git-dir=${join(repo, ".git")}`;
if (typeof args === "string") args = args.split(" ");
const process = Deno.run({
cwd: repo,
cmd: ["git", dir, ...args],
stdout: "piped",
stderr: "piped",

const cmd = new Deno.Command("git", {
args: [dir, ...args],
});
const output = await process.output();
const err = await process.stderrOutput();
const status = await process.status();
process.close();
return [status, decoder.decode(output), decoder.decode(err)];
const process = cmd.outputSync();
return [
process.success,
decoder.decode(process.stdout),
decoder.decode(process.stderr),
];
}

export async function ezgit(
export function ezgit(
repo: string,
args: string[] | string,
): Promise<void> {
const [status, _, err] = await git(repo, args);
if (!status.success) throw new ReleaseError("GIT_EXE", err);
): void {
const [success, _, err] = git(repo, args);
if (!success) throw new ReleaseError("GIT_EXE", err);
}

export async function fetchConfig(repo: string): Promise<GitConfig> {
Expand Down
20 changes: 20 additions & 0 deletions tools/.release_up.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"changelog": {},
"github": {
"release": true
},
"regex": [
{
"file": "README.md",
"patterns": [
"(?<=@)(.*)(?=\/cli)"
]
},
{
"file": "deno.json",
"patterns": [
"(?<=\"version\": \")(.*)(?=\",)"
]
}
]
}
3 changes: 0 additions & 3 deletions version.json

This file was deleted.

Loading