Skip to content

Commit

Permalink
chore: organize and refactor mkrepo (#201)
Browse files Browse the repository at this point in the history
Move all the repo generation code to a directory `.mkrepo` and create a script called `./mkrepo.sh` at the root of the repository to execute it.

Refactor the code by enriching the API of `Library` to encapsulate all the logic in one place.
  • Loading branch information
eladb authored Apr 12, 2024
1 parent 4ed1136 commit 928a7fb
Show file tree
Hide file tree
Showing 14 changed files with 101 additions and 55 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/pull-request-diff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ jobs:
- name: Install winglang
run: npm i -g winglang
- name: Update config files
run: wing compile generate-workflows.main.w
run: ./mkrepo.sh
- name: Check for missing changes
run: git diff --exit-code || (echo 'Please run "wing compile
generate-workflows.main.w" from the root of the repository, and commit
any changes to your branch.' && exit 1)
run: git diff --exit-code || (echo 'Please run "./mkrepo.sh" from the root of
the repository, and commit any changes to your branch.' && exit 1)
11 changes: 6 additions & 5 deletions canary.w → .mkrepo/canary.w
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
bring fs;
bring "./library.w" as l;

pub class CanaryWorkflow {
new(workflowdir: str, libs: Array<str>, skipLibs: Array<str>?) {
new(workflowdir: str, libs: Array<l.Library>, skipLibs: Array<str>?) {
let testLibSteps = (lib: str): Array<Json> => {
let var testCommand = "wing test";

Expand Down Expand Up @@ -57,13 +58,13 @@ pub class CanaryWorkflow {

let jobs = MutJson {};
for lib in libs {
if (skipLibs ?? []).contains(lib) {
if (skipLibs ?? []).contains(lib.name) {
continue;
}
jobs.set("canary-{lib}", {
name: "Test {lib}",
jobs.set("canary-{lib.name}", {
name: "Test {lib.name}",
"runs-on": "ubuntu-latest",
steps: testLibSteps(lib),
steps: testLibSteps(lib.name),
});
}

Expand Down
51 changes: 37 additions & 14 deletions library.w → .mkrepo/library.w
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,42 @@ bring fs;

struct PackageManifest {
name: str;
wing: WingOptions?;
}

struct WingOptions {
platforms: Array<str>?;
}

pub class Library {
extern "./util.js" static sortedArray(arr: Array<str>): Array<str>;

pub name: str;
pub dir: str; // relative to root of the repo
pub platforms: Array<str>;
pub buildJob: str;
pub manifest: PackageManifest; // package.json

new(workflowdir: str, libdir: str) {
this.dir = libdir;
this.name = fs.basename(libdir);
let pkgjsonpath = "{libdir}/package.json";
let pkgjson = fs.readJson(pkgjsonpath);
let manifest = PackageManifest.fromJson(pkgjson);
log(manifest.name);
let base = fs.basename(libdir);
let expected = "@winglibs/{base}";
if manifest.name != expected {
this.manifest = PackageManifest.fromJson(pkgjson);

log(this.manifest.name);
this.buildJob = "build-{this.name}";
let expected = "@winglibs/{this.name}";
if this.manifest.name != expected {
throw "'name' in {pkgjsonpath} is expected to be {expected}";
}


this.platforms = Library.sortedArray(this.manifest.wing?.platforms ?? []);
if this.platforms.length == 0 {
throw "\"{this.name}\" winglib does not have a `wing.platforms` field in its package.json.";
}

let addCommonSteps = (steps: MutArray<Json>) => {
let var testCommand = "wing test";

Expand Down Expand Up @@ -62,7 +84,6 @@ pub class Library {
run: "wing pack",
"working-directory": libdir,
});

};

let releaseSteps = MutArray<Json>[];
Expand All @@ -86,7 +107,7 @@ pub class Library {
}
});

let tagName = "{base}-v\$\{\{ env.WINGLIB_VERSION \}\}";
let tagName = "{this.name}-v\$\{\{ env.WINGLIB_VERSION \}\}";
let githubTokenWithAuth = "\$\{\{ secrets.PROJEN_GITHUB_TOKEN }}";

releaseSteps.push({
Expand All @@ -102,20 +123,20 @@ pub class Library {
name: "GitHub release",
uses: "softprops/action-gh-release@v1",
with: {
name: "{base} v\$\{\{ env.WINGLIB_VERSION \}\}",
name: "{this.name} v\$\{\{ env.WINGLIB_VERSION \}\}",
tag_name: tagName,
files: "*.tgz",
token: githubTokenWithAuth,
},
});

let releaseJobs = MutJson {};
releaseJobs.set("build-{base}", {
releaseJobs.set(this.buildJob, {
"runs-on": "ubuntu-latest",
steps: releaseSteps.copy(),
});
fs.writeYaml("{workflowdir}/{base}-release.yaml", {
name: "{base}-release",
fs.writeYaml("{workflowdir}/{this.name}-release.yaml", {
name: "{this.name}-release",
on: {
push: {
branches: ["main"],
Expand All @@ -129,12 +150,14 @@ pub class Library {
});

let pullJobs = MutJson {};
pullJobs.set("build-{base}", {

pullJobs.set("build-{this.name}", {
"runs-on": "ubuntu-latest",
steps: pullSteps.copy(),
});
fs.writeYaml("{workflowdir}/{base}-pull.yaml", {
name: "{base}-pull",

fs.writeYaml("{workflowdir}/{this.name}-pull.yaml", {
name: "{this.name}-pull",
on: {
pull_request: {
paths: ["{libdir}/**"],
Expand Down
11 changes: 7 additions & 4 deletions generate-workflows.main.w → .mkrepo/main.w
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ let workflowdir = ".github/workflows";
fs.remove(workflowdir);
fs.mkdir(workflowdir);

let libs = MutArray<str>[];
let libs = MutArray<l.Library>[];

for file in fs.readdir(".") {
if file.startsWith(".") {
continue;
}

if !fs.exists("{file}/package.json") {
log("skipping {file}");
continue;
}

new l.Library(workflowdir, file) as file;
libs.push(file);
let lib = new l.Library(workflowdir, file) as file;
libs.push(lib);
}

readme.update(libs.copy());
Expand Down
10 changes: 6 additions & 4 deletions mergify.w → .mkrepo/mergify.w
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
bring fs;
bring "./library.w" as l;

pub class MergifyWorkflow {
new(libs: Array<str>) {
new(libs: Array<l.Library>) {
let buildChecks = MutArray<Json>[];
buildChecks.push("check-success=Validate PR title");
buildChecks.push("check-success=Check for mutations");

for lib in libs {
buildChecks.push("-check-failure=build-{lib}");
buildChecks.push("-check-pending=build-{lib}");
buildChecks.push("-check-stale=build-{lib}");
buildChecks.push("-check-failure={lib.buildJob}");
buildChecks.push("-check-pending={lib.buildJob}");
buildChecks.push("-check-stale={lib.buildJob}");
}

fs.writeYaml(".mergify.yml", {
Expand Down
4 changes: 2 additions & 2 deletions pr-diff.w → .mkrepo/pr-diff.w
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ pub class PullRequestDiffWorkflow {
},
{
"name": "Update config files",
"run": "wing compile generate-workflows.main.w",
"run": "./mkrepo.sh",
},
{
"name": "Check for missing changes",
"run": "git diff --exit-code || (echo 'Please run \"wing compile generate-workflows.main.w\" from the root of the repository, and commit any changes to your branch.' && exit 1)",
"run": "git diff --exit-code || (echo 'Please run \"./mkrepo.sh\" from the root of the repository, and commit any changes to your branch.' && exit 1)",
},
],
},
Expand Down
11 changes: 9 additions & 2 deletions pr-lint.w → .mkrepo/pr-lint.w
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
bring fs;
bring "./library.w" as l;

pub class PullRequestLintWorkflow {
new(workflowdir: str, libs: Array<str>) {
new(workflowdir: str, libs: Array<l.Library>) {
let var types = MutArray<str>[
"feat",
"fix",
Expand All @@ -10,7 +11,13 @@ pub class PullRequestLintWorkflow {
"rfc",
"revert",
];
types = types.concat(libs.copyMut());

let names = MutArray<str>[];
for l in libs {
names.push(l.name);
}

types = types.concat(names);

fs.writeYaml("{workflowdir}/pull-request-lint.yaml", {
name: "Pull Request Lint",
Expand Down
20 changes: 7 additions & 13 deletions readme.w → .mkrepo/readme.w
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
bring fs;
bring "./library.w" as l;

pub class Util {
extern "./util.js" static arraySlice(arr: Array<str>, start: num, end: num): MutArray<str>;
extern "./util.js" static arraySort(arr: MutArray<str>): void;

pub static update(libraries: Array<str>) {
pub static update(libraries: Array<l.Library>) {
let readme = fs.readFile("README.md");
let lines = readme.split("\n");

Expand All @@ -20,20 +20,14 @@ pub class Util {
newLines.push("| Library | npm package | Platforms |");
newLines.push("| --- | --- | --- |");
for lib in libraries {
let var line = "| [{lib}](./{lib})";
line += " | [@winglibs/{lib}](https://www.npmjs.com/package/@winglibs/{lib})";
let pkgJson = fs.readFile("{lib}/package.json");
let pkg = Json.parse(pkgJson);
let platforms: MutArray<str> = unsafeCast(pkg.tryGet("wing")?.tryGet("platforms")) ?? [];
if platforms.length == 0 {
throw "\"{lib}\" winglib does not have a `wing.platforms` field in its package.json.";
}
Util.arraySort(platforms);
line += " | " + platforms.join(", ") + " |";
let var line = "| [{lib.name}](./{lib.dir})";
line += " | [@winglibs/{lib.name}](https://www.npmjs.com/package/@winglibs/{lib.name})";
let pkg = lib.manifest;
line += " | " + lib.platforms.join(", ") + " |";
newLines.push(line);
}
newLines.push("");
newLines.push("_Generated with `wing compile generate-workflows.w`. To update the list of supported platforms for a winglib, please update the \"wing\" section in its package.json file._");
newLines.push("_Generated with `mkrepo.sh`. To update the list of supported platforms for a winglib, please update the \"wing\" section in its package.json file._");
newLines.push("");
let finalLines = newLines.concat(Util.arraySlice(lines, end, lines.length));

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion util.extern.d.ts → .mkrepo/util.extern.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default interface extern {
arraySlice: (arr: (readonly (string)[]), start: number, end: number) => (string)[],
arraySort: (arr: (string)[]) => void,
sortedArray: (arr: (readonly (string)[])) => (readonly (string)[]),
}
5 changes: 3 additions & 2 deletions util.js → .mkrepo/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
exports.arraySlice = function(array, start, end) {
return Array.prototype.slice.call(array, start, end);
};
exports.arraySort = function(array) {
return Array.prototype.sort.call(array);

exports.sortedArray = function(array) {
return array.sort();
}
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Welcome! You've arrived to the warm and cozy home of the *Wing Trusted Library Ecosystem*.

This repository hosts the code for [Wing](https://winglang.io) libraries that we consider trusted
and that meet our community's quality bar.
This repository hosts the code for [Wing](https://winglang.io) libraries (also called "winglibs")
that we consider trusted and that meet our community's quality bar.

One of the cool things about trusted libraries is that we take care of building, testing and
publishing them for you.
Expand Down Expand Up @@ -35,10 +35,24 @@ publishing them for you.
| [vite](./vite) | [@winglibs/vite](https://www.npmjs.com/package/@winglibs/vite) | sim, tf-aws |
| [websockets](./websockets) | [@winglibs/websockets](https://www.npmjs.com/package/@winglibs/websockets) | awscdk, sim, tf-aws |

_Generated with `wing compile generate-workflows.w`. To update the list of supported platforms for a winglib, please update the "wing" section in its package.json file._
_Generated with `mkrepo.sh`. To update the list of supported platforms for a winglib, please update the "wing" section in its package.json file._

<!-- WINGLIBS_TOC_END -->

## How is this repository structured?

The code for each library is located in a subdirectory named after the library. For example, the
`websockets` library is located under [`./websockets`](./websockets/).

Wing libraries are published to npm under the `@winglibs` scope, and there's a `package.json` file
in the library's directory.

A set of GitHub Workflows are maintained for each library under the [.github](./github/) directory.
These workflows, as well as other artifacts in this repository (such as the table of contents in
this README) are are generated using a tool called `mkrepo`, which can be executed using the
`./mkrepo.sh` script at the root of this repository. The source code for this tool is can be found
under [.mkrepo](./.mkrepo/) (and it is written in Wing of course).

## How do I add a new library?

It's so damn easy.
Expand Down
2 changes: 1 addition & 1 deletion mklib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ HERE

cp ./LICENSE $1/

wing compile generate-workflows.main.w
./mkrepo.sh
rm -fr target/

cd $1
Expand Down
2 changes: 2 additions & 0 deletions mkrepo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
wing compile .mkrepo/main.w

0 comments on commit 928a7fb

Please sign in to comment.