Skip to content

Commit

Permalink
Merge pull request #1074 from polywrap/go-codegen
Browse files Browse the repository at this point in the history
Golang Wrap Support
  • Loading branch information
dOrgJelli authored Jul 13, 2023
2 parents 31e18fb + ce4a9c1 commit 6546137
Show file tree
Hide file tree
Showing 120 changed files with 6,530 additions and 522 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/ci-golang.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI-Golang

on:
push:
branches:
- origin
- origin-dev
pull_request:

jobs:
Test-Cli:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Read .nvmrc
run: echo ::set-output name=NVMRC::$(cat .nvmrc)
id: nvm

- name: Setup Node.js
uses: actions/setup-node@master
with:
node-version: '${{ steps.nvm.outputs.NVMRC }}'

- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v2
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --nonInteractive --frozen-lockfile --prefer-offline

- name: Build
run: yarn build

- name: Test
run: yarn test:golang
working-directory: ./packages/cli
3 changes: 2 additions & 1 deletion packages/cli/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module.exports = {
modulePathIgnorePatterns: [
"<rootDir>/build",
"<rootDir>/src/__tests__/project/.polywrap",
"<rootDir>/src/__tests__/e2e/build-rs.spec.ts"
"<rootDir>/src/__tests__/e2e/build-rs.spec.ts",
"<rootDir>/src/__tests__/e2e/build-go.spec.ts"
],
testPathIgnorePatterns: [
"<rootDir>/src/__tests__/project/.polywrap"
Expand Down
22 changes: 22 additions & 0 deletions packages/cli/jest.go.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = {
collectCoverage: true,
preset: "ts-jest",
testEnvironment: "node",
globals: {
"ts-jest": {
diagnostics: false
},
},
modulePathIgnorePatterns: [
"<rootDir>/build",
"<rootDir>/src/__tests__/project/.polywrap"
],
testPathIgnorePatterns: [
"<rootDir>/src/__tests__/project/.polywrap"
],
transformIgnorePatterns: [
"<rootDir>/src/__tests__/project/.polywrap"
],
setupFilesAfterEnv: ["./jest.setup.js"],
testMatch: ["**/build-go.spec.ts"]
};
4 changes: 4 additions & 0 deletions packages/cli/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"commands_build_description": "Build Polywrap Projects (type: interface, wasm)",
"commands_build_error_manifestPathMissing": "{option} option missing {argument} argument",
"commands_build_error_manifestNotFound": "Manifest not found. Search paths used: {paths}",
"commands_build_error_goModNotFound": "go.mod file not found. Search paths used: {paths}",
"commands_build_error_outputDirMissingPath": "{option} option missing {argument} argument",
"commands_build_error_unsupportedProjectType": "Unsupported project type. You can only build the following project types: {supportedTypes}",
"commands_build_keypressListener_exit": "Exit: [CTRL + C], [ESC], or [Q]",
Expand Down Expand Up @@ -233,6 +234,8 @@
"lib_helpers_deployManifestExt_loadError": "Failed to load deploy manifest extension from {path}",
"lib_helpers_deployManifestExt_loadText": "Load manifest extension from {path}",
"lib_helpers_deployManifestExt_loadWarning": "No manifest extension found in {path}",
"lib_helpers_gomod_unableToLoad": "Unable to load go.mod: {path}",
"lib_helpers_gomod_invalid": "Invalid format of go.mod: {path}",
"lib_helpers_manifest_outputError": "Failed to output manifest to {path}",
"lib_helpers_manifest_outputText": "Manifest written to {path}",
"lib_helpers_manifest_outputWarning": "Warnings writing manifest to {path}",
Expand Down Expand Up @@ -272,6 +275,7 @@
"lib_typescript_tsNodeNotInstalled": "Your project uses typescript, but ts-node is not installed",
"lib_watcher_alreadyWatching": "Watcher session is already in progress. Directory: {dir}",
"lib_wasm_rust_invalidModule": "Module paths must point to Cargo.toml files. Found: {path}",
"lib_wasm_golang_invalidModule": "Module paths must point to go.mod file. Found: {path}",
"lib_docker_invalidImageId": "Invalid docker image ID returned: {imageId}",
"lib_docker_noInstall": "Docker executable not found in PATH",
"lib_infra_unrecognizedModule": "Unrecognized modules: {modules}. Default modules: {defaultModules}",
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"commands_build_description": "Build Polywrap Projects (type: interface, wasm)",
"commands_build_error_manifestPathMissing": "{option} option missing {argument} argument",
"commands_build_error_manifestNotFound": "Manifest not found. Search paths used: {paths}",
"commands_build_error_goModNotFound": "go.mod file not found. Search paths used: {paths}",
"commands_build_error_outputDirMissingPath": "{option} option missing {argument} argument",
"commands_build_error_unsupportedProjectType": "Unsupported project type. You can only build the following project types: {supportedTypes}",
"commands_build_keypressListener_exit": "Exit: [CTRL + C], [ESC], or [Q]",
Expand Down Expand Up @@ -233,6 +234,8 @@
"lib_helpers_deployManifestExt_loadError": "Failed to load deploy manifest extension from {path}",
"lib_helpers_deployManifestExt_loadText": "Load manifest extension from {path}",
"lib_helpers_deployManifestExt_loadWarning": "No manifest extension found in {path}",
"lib_helpers_gomod_unableToLoad": "Unable to load go.mod: {path}",
"lib_helpers_gomod_invalid": "Invalid format of go.mod: {path}",
"lib_helpers_manifest_outputError": "Failed to output manifest to {path}",
"lib_helpers_manifest_outputText": "Manifest written to {path}",
"lib_helpers_manifest_outputWarning": "Warnings writing manifest to {path}",
Expand Down Expand Up @@ -272,6 +275,7 @@
"lib_typescript_tsNodeNotInstalled": "Your project uses typescript, but ts-node is not installed",
"lib_watcher_alreadyWatching": "Watcher session is already in progress. Directory: {dir}",
"lib_wasm_rust_invalidModule": "Module paths must point to Cargo.toml files. Found: {path}",
"lib_wasm_golang_invalidModule": "Module paths must point to go.mod file. Found: {path}",
"lib_docker_invalidImageId": "Invalid docker image ID returned: {imageId}",
"lib_docker_noInstall": "Docker executable not found in PATH",
"lib_infra_unrecognizedModule": "Unrecognized modules: {modules}. Default modules: {defaultModules}",
Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"test:e2e:p1": "yarn test:cmd -- ./src/__tests__/e2e/p1/*.spec.ts",
"test:e2e:p2": "yarn test:cmd -- ./src/__tests__/e2e/p2/*.spec.ts",
"test:rust": "yarn test:cmd -- --config ./jest.rs.config.js",
"test:golang": "yarn test:cmd -- --config ./jest.go.config.js",
"test:watch": "yarn test -- --watch"
},
"resolutions": {
Expand Down
72 changes: 72 additions & 0 deletions packages/cli/src/__tests__/e2e/build-go.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { polywrapCli } from "./utils";
import { Commands } from "@polywrap/cli-js";
import { GetPathToCliTestFiles } from "@polywrap/test-cases";
import fs from "fs";
import path from "path";

jest.setTimeout(1500000);

describe("e2e tests for build command", () => {
const testCaseRoot = path.join(GetPathToCliTestFiles(), "build-cmd/wasm/golang");
const testCases = fs
.readdirSync(testCaseRoot, { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);

const getTestCaseDir = (index: number) =>
path.join(testCaseRoot, testCases[index]);

describe("Image strategy", () => {
it("Builds for go", async () => {
const { exitCode: code, stdout: output } = await Commands.build({
strategy: "image",
verbose: true
}, {
cwd: getTestCaseDir(0),
cli: polywrapCli,
});
const buildDir = `./build`;

expect(code).toEqual(0);
expect(output).toContain(`Artifacts written to ${buildDir}`);
expect(output).toContain(`WRAP manifest written in ${buildDir}/wrap.info`);
});
})

// NOTE: Skipped because CI needs system prequisites: golang
describe.skip("Local strategy", () => {
it("Builds for rust", async () => {
const { exitCode: code, stdout: output } = await Commands.build({
strategy: "local",
verbose: true
}, {
cwd: getTestCaseDir(0),
cli: polywrapCli,
});

const buildDir = `./build`;

expect(code).toEqual(0);
expect(output).toContain(`Artifacts written to ${buildDir}`);
expect(output).toContain(`WRAP manifest written in ${buildDir}/wrap.info`);
});
})

describe("VM strategy", () => {
it("Builds for go", async () => {
const { exitCode: code, stdout: output } = await Commands.build({
strategy: "vm",
verbose: true
}, {
cwd: getTestCaseDir(0),
cli: polywrapCli,
});

const buildDir = `./build`;

expect(code).toEqual(0);
expect(output).toContain(`Artifacts written to ${buildDir}`);
expect(output).toContain(`WRAP manifest written in ${buildDir}/wrap.info`);
});
})
});
1 change: 0 additions & 1 deletion packages/cli/src/__tests__/e2e/p1/help.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Commands:
codegen|g [options] Generate Code For Polywrap Projects
create|c Create New Projects
deploy|d [options] Deploys Polywrap Projects
docgen|o [options] <action> Generate wrapper documentation
infra|i [options] <action> Modular Infrastructure-As-Code Orchestrator
manifest|m Inspect & Migrade Polywrap Manifests
test|t [options] Execute Tests
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/__tests__/e2e/p1/no-command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ Commands:
codegen|g [options] Generate Code For Polywrap Projects
create|c Create New Projects
deploy|d [options] Deploys Polywrap Projects
docgen|o [options] <action> Generate wrapper documentation
infra|i [options] <action> Modular Infrastructure-As-Code Orchestrator
manifest|m Inspect & Migrade Polywrap Manifests
test|t [options] Execute Tests
Expand Down
7 changes: 4 additions & 3 deletions packages/cli/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
polywrapManifestLanguages,
pluginManifestLanguages,
parseWrapperEnvsOption,
parseDirOptionNoDefault,
} from "../lib";
import { CodeGenerator } from "../lib/codegen";
import {
Expand Down Expand Up @@ -48,7 +49,7 @@ export interface BuildCommandOptions extends BaseCommandOptions {
clientConfig: string | false;
wrapperEnvs: string | false;
noCodegen: boolean;
codegenDir: string;
codegenDir: string | false;
watch: boolean;
strategy: `${SupportedStrategies}`;
}
Expand Down Expand Up @@ -112,7 +113,7 @@ export const build: Command = {
wrapperEnvs: options.wrapperEnvs || false,
outputDir: parseDirOption(options.outputDir, defaultOutputDir),
noCodegen: !options.codegen || false,
codegenDir: parseDirOption(options.codegenDir, DEFAULT_CODEGEN_DIR),
codegenDir: parseDirOptionNoDefault(options.codegenDir),
strategy: options.strategy || defaultStrategy,
watch: options.watch || false,
verbose: options.verbose || false,
Expand Down Expand Up @@ -241,7 +242,7 @@ async function run(options: Required<BuildCommandOptions>) {
const codeGenerator = new CodeGenerator({
project,
schemaComposer,
codegenDirAbs: codegenDir,
codegenDirAbs: codegenDir || undefined,
});
const codegenSuccess = await codeGenerator.generate();

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/Compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Compiler {
await this._outputWrapManifest();

if (await this._isWasm()) {
// Build & Output: wasm.wrap
// Build & Output: wrap.wasm
await this._buildModules();

// Copy: Resources folder
Expand Down
36 changes: 36 additions & 0 deletions packages/cli/src/lib/build-strategies/BuildOverrides.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { PolywrapManifestLanguage } from "../";

import { PolywrapManifest } from "@polywrap/polywrap-manifest-types-js";
import path from "path";
import fs from "fs";

export interface BuildOverrides {
validateManifest?: (manifest: PolywrapManifest) => Promise<void>;

sourcesSubDirectory?: string;
}

export async function tryGetBuildOverrides(
language: PolywrapManifestLanguage
): Promise<BuildOverrides | undefined> {
const modulePath = path.join(
__dirname,
"..",
"defaults",
"language-overrides",
language,
"index.js"
);
let overrides: BuildOverrides | undefined;

if (fs.existsSync(modulePath)) {
const module = await import(modulePath);

// Get any build overrides for the given build-image
if (module.getBuildOverrides) {
overrides = module.getBuildOverrides() as BuildOverrides;
}
}

return Promise.resolve(overrides);
}
22 changes: 16 additions & 6 deletions packages/cli/src/lib/build-strategies/BuildStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { BuildOverrides, tryGetBuildOverrides } from "./BuildOverrides";
import { PolywrapProject } from "../project";

import fse from "fs-extra";
import path from "path";

export interface BuildStrategyArgs {
export interface BuildStrategyConfig {
project: PolywrapProject;
outputDir: string;
}

export abstract class BuildStrategy<TBuildReturn = unknown> {
protected project: PolywrapProject;
protected outputDir: string;
protected overrides?: BuildOverrides;

constructor({ project, outputDir }: BuildStrategyArgs) {
constructor({ project, outputDir }: BuildStrategyConfig) {
this.project = project;
this.outputDir = outputDir;
}
Expand All @@ -23,25 +25,33 @@ export abstract class BuildStrategy<TBuildReturn = unknown> {

async build(): Promise<TBuildReturn> {
const language = await this.project.getManifestLanguage();
const defaultsOfStrategyUsed = path.join(
const buildStrategyDir = path.join(
__dirname,
"..",
"defaults",
"build-strategies",
language,
this.getStrategyName()
);

// Cache all build strategy files
const strategyUsedCacheDir = this.project.getCachePath(
PolywrapProject.cacheLayout.buildStrategyUsed
);

if (fse.existsSync(strategyUsedCacheDir)) {
fse.removeSync(strategyUsedCacheDir);
}

fse.mkdirSync(strategyUsedCacheDir, { recursive: true });
fse.copySync(buildStrategyDir, strategyUsedCacheDir);

// Check if build overrides exist
this.overrides = await tryGetBuildOverrides(language);

// If they do, ensure the manifest if valid before build starts
if (this.overrides && this.overrides.validateManifest) {
await this.overrides.validateManifest(await this.project.getManifest());
}

fse.copySync(defaultsOfStrategyUsed, strategyUsedCacheDir);
return this.buildSources();
}
}
1 change: 1 addition & 0 deletions packages/cli/src/lib/build-strategies/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./BuildOverrides";
export * from "./BuildStrategy";
export * from "./strategies";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
runCommand,
runCommandSync,
} from "../../system";
import { BuildStrategyArgs, BuildStrategy } from "../BuildStrategy";
import { BuildStrategyConfig, BuildStrategy } from "../BuildStrategy";
import { intlMsg } from "../../intl";
import { logActivity } from "../../logging";

Expand All @@ -21,8 +21,8 @@ type BuildImageId = string;
export class DockerImageBuildStrategy extends BuildStrategy<BuildImageId> {
private _dockerLock: FileLock;

constructor(args: BuildStrategyArgs) {
super(args);
constructor(config: BuildStrategyConfig) {
super(config);

if (!isDockerInstalled(this.project.logger)) {
throw new Error(intlMsg.lib_docker_noInstall());
Expand Down
Loading

0 comments on commit 6546137

Please sign in to comment.