Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4248 from trufflesuite/supplier/package
Browse files Browse the repository at this point in the history
Make dedicated @truffle/supplier package
  • Loading branch information
gnidan authored Aug 16, 2021
2 parents f88640d + 88aa51c commit 4d2cff7
Show file tree
Hide file tree
Showing 21 changed files with 447 additions and 14 deletions.
3 changes: 0 additions & 3 deletions packages/compile-common/src/compilerSupplier/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/compile-common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export { Profiler } from "./profiler";
export * as CompilerSupplier from "./compilerSupplier";
export * as Shims from "./shims";
export * as Sources from "./sources";
export * as Errors from "./errors";
Expand Down
2 changes: 2 additions & 0 deletions packages/supplier/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
node_modules/
95 changes: 95 additions & 0 deletions packages/supplier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# @truffle/supplier

This package provides infrastructure for the rest of Truffle, defining the
concept of a "supplier", a component that downloads a specific version of some
desired code resource according to one or more strategies. (For example,
@truffle/compile-solidity comprises its "CompilerSupplier", which fetches
specific solc versions from the web / via docker / et al.)

## Usage example

1. Define a common "results" specification: what does `supplier.load()` and
`supplier.list()` return?

e.g.:

```typescript
export type Compiler = { compile(): any };

export namespace Results {
export type Specification = {
load: Promise<Compiler>;
list: Promise<string[]>;
};
}
```

2. Define one or more strategies.

e.g.:

```typescript
import { Mixin } from "ts-mixer";

import {
Strategy,
AllowsLoadingSpecificVersion,
AllowsListingVersions
} from "@truffle/supplier";

import { Results } from "./types";

export namespace RemoteSoljson {
export type Specification = {
constructor: {
options: { strategy: "remote-soljson" };
};
results: Results.Specification;
allowsLoadingSpecificVersion: true;
allowsListingVersions: true;
};
}

export class RemoteSoljson
extends Mixin(AllowsLoadingSpecificVersion, AllowsListingVersions)
implements Strategy<RemoteSoljson.Specification> {
async load(_version?: string) {
return { compile: (): any => null };
}

async list(): Promise<string[]> {
return [];
}
}
```

3. Connect everything:

e.g.:

```typescript
import { Supplier, forDefinition } from "@truffle/supplier";

import { Results } from "./types";
import { RemoteSoljson } from "./remote-soljson";

export type Specification = {
results: Results.Specification;
options: {};
strategies: {
"remote-soljson": RemoteSoljson.Specification;
};
};

export const definition: Supplier.Definition<Specification> = {
determineStrategy({ strategy }) {
return strategy;
},

strategyConstructors: {
"remote-soljson": RemoteSoljson
}
};

export const createCompilerSupplier = forDefinition(definition);
```
46 changes: 46 additions & 0 deletions packages/supplier/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@truffle/supplier",
"version": "0.1.0-0",
"description": "Infrastructure for downloading specific compiler versions, etc.",
"main": "lib/supplier.js",
"types": "dist/src/index.d.ts",
"author": "g. nicholas d'andrea <gnidan@trufflesuite.com>",
"license": "MIT",
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/trufflesuite/truffle.git",
"directory": "packages/supplier"
},
"scripts": {
"build": "ttsc",
"prepare": "yarn build",
"test": "yarn test:code && yarn test:types",
"test:code": "mocha -r ./test/setup.js **/*.test.ts",
"test:types": "yarn build && tsd",
"watch": "yarn build --watch"
},
"bugs": {
"url": "https://github.com/trufflesuite/truffle/issues"
},
"devDependencies": {
"@types/mocha": "^5.2.7",
"@types/node": "12.12.21",
"mocha": "8.0.1",
"ts-node": "^9.0.0",
"tsd": "^0.17.0",
"ttypescript": "^1.5.12",
"typescript": "^4.2.0",
"typescript-transform-paths": "^3.2.1"
},
"dependencies": {
"colors": "^1.4.0",
"debug": "^4.3.1",
"ts-mixer": "^6.0.0"
}
}
10 changes: 10 additions & 0 deletions packages/supplier/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export { Constructor } from "./constructor";
export { Results } from "./results";
export { Strategy, BaseStrategy } from "./strategy";
export { Supplier, forDefinition } from "./supplier";
export {
AllowsLoadingSpecificVersion,
AllowsListingVersions,
ForbidsLoadingSpecificVersion,
ForbidsListingVersions
} from "./mixin";
23 changes: 23 additions & 0 deletions packages/supplier/src/mixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export class AllowsLoadingSpecificVersion {
allowsLoadingSpecificVersion(): true {
return true;
}
}

export class ForbidsLoadingSpecificVersion {
allowsLoadingSpecificVersion(): false {
return false;
}
}

export class AllowsListingVersions {
allowsListingVersions(): true {
return true;
}
}

export class ForbidsListingVersions {
allowsListingVersions(): false {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Results as FreeResults } from "./results";

export namespace Strategy {
/**
* Type-level description of a compiler supplier strategy
* Type-level description of a supplier strategy
*/
export type Specification = {
constructor: Omit<FreeConstructor.Specification, "result">;
Expand Down
45 changes: 45 additions & 0 deletions packages/supplier/src/supplier.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import assert from "assert";

import { createCompilerSupplier, Native, RemoteSoljson } from "test/example";

describe("Supplier.forDefinition", function () {
it("selects the correct strategy", async function () {
{
const supplier = createCompilerSupplier({ strategy: "native" });

assert.ok(supplier instanceof Native);
}

{
const supplier = createCompilerSupplier({ strategy: "remote-soljson" });

assert.ok(supplier instanceof RemoteSoljson);
}
});

it("allows listing only when strategy allows it", async function() {
{
const supplier = createCompilerSupplier({ strategy: "native" });
assert(!supplier.allowsListingVersions());

try {
// @ts-expect-error
await supplier.list();

assert.fail("Should have thrown error");
} catch {}
}

{
const supplier = createCompilerSupplier({ strategy: "remote-soljson" });

if (!supplier.allowsListingVersions()) {
throw new Error("Strategy should allow listing versions");
}

const versions = await supplier.list();

assert.deepEqual(versions, []);
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export namespace Supplier {

/**
* An object of type Supplier<S, N> provides an interface for loading and
* possibly listing versions of the compiler
* possibly listing versions of the supplied component
*
* @dev for known strategy names, this computes the method signature of
* `load()` according to the corresponding strategy specification;
Expand Down
39 changes: 39 additions & 0 deletions packages/supplier/test-d/supplier.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { expectType, expectError } from "tsd";

import { Compiler, createCompilerSupplier } from "test/example";


{
const supplier = createCompilerSupplier<"remote-soljson">({
strategy: "remote-soljson"
});

supplier.load("0.5.0");
supplier.list();
}

{
const supplier = createCompilerSupplier<"native">({ strategy: "native" });

expectType<Promise<Compiler>>(supplier.load());
// errors:
expectError(supplier.load("0.5.0"));
expectError(supplier.list());
}

{
const supplier = createCompilerSupplier({ strategy: "remote-soljson" });

expectType<Promise<Compiler>>(supplier.load());
// errors:
expectError(supplier.load("0.5.0"));
expectError(supplier.list());

if (supplier.allowsLoadingSpecificVersion()) {
expectType<Promise<Compiler>>(supplier.load("0.1.0"));
}

if (supplier.allowsListingVersions()) {
expectType<Promise<string[]>>(supplier.list());
}
}
Empty file added packages/supplier/test/.gitkeep
Empty file.
30 changes: 30 additions & 0 deletions packages/supplier/test/example/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Supplier, forDefinition } from "@truffle/supplier";

import { Results } from "./types";
import { Native } from "./native";
import { RemoteSoljson } from "./remote-soljson";

export type Specification = {
results: Results.Specification;
options: {};
strategies: {
"native": Native.Specification;
"remote-soljson": RemoteSoljson.Specification
}
};

export const definition: Supplier.Definition<Specification> = {
determineStrategy({ strategy }) {
return strategy;
},

strategyConstructors: {
"native": Native,
"remote-soljson": RemoteSoljson
}
};

export const createCompilerSupplier = forDefinition(definition);

export type { Compiler } from "./types";
export { Native, RemoteSoljson };
29 changes: 29 additions & 0 deletions packages/supplier/test/example/native.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Mixin } from "ts-mixer";

import {
Strategy,
ForbidsLoadingSpecificVersion,
ForbidsListingVersions
} from "@truffle/supplier";

import { Results } from "./types";

export namespace Native {
export type Specification = {
constructor: {
options: { strategy: "native" };
};
results: Results.Specification;
allowsLoadingSpecificVersion: false;
allowsListingVersions: false;
};
}

export class Native
extends Mixin(ForbidsLoadingSpecificVersion, ForbidsListingVersions)
implements Strategy<Native.Specification>
{
async load() {
return { compile: (): any => null };
}
}
33 changes: 33 additions & 0 deletions packages/supplier/test/example/remote-soljson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Mixin } from "ts-mixer";

import {
Strategy,
AllowsLoadingSpecificVersion,
AllowsListingVersions
} from "@truffle/supplier";

import { Results } from "./types";

export namespace RemoteSoljson {
export type Specification = {
constructor: {
options: { strategy: "remote-soljson" };
};
results: Results.Specification;
allowsLoadingSpecificVersion: true;
allowsListingVersions: true;
};
}

export class RemoteSoljson
extends Mixin(AllowsLoadingSpecificVersion, AllowsListingVersions)
implements Strategy<RemoteSoljson.Specification>
{
async load(_version?: string) {
return { compile: (): any => null };
}

async list(): Promise<string[]> {
return [];
}
}
9 changes: 9 additions & 0 deletions packages/supplier/test/example/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export type Compiler = { compile(): any };

export namespace Results {
export type Specification = {
load: Promise<Compiler>;
list: Promise<string[]>;
};
}

Loading

0 comments on commit 4d2cff7

Please sign in to comment.