Skip to content

Commit

Permalink
feat!: Regex can now be applied to any file (#22)
Browse files Browse the repository at this point in the history
* maybe

* assert -> with

* add file path in config.

* lint - remove deno.run
  • Loading branch information
sylc committed Feb 10, 2024
1 parent e7caf2d commit d506093
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 56 deletions.
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.

0 comments on commit d506093

Please sign in to comment.