Skip to content

Commit

Permalink
Finish initial migration to VM2 based danger runner:
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed Aug 11, 2017
1 parent e2e8a7d commit 58dc72a
Show file tree
Hide file tree
Showing 16 changed files with 261 additions and 629 deletions.
5 changes: 3 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
"name": "Debug Jest",
"type": "node",
"request": "launch",
"runtimeArgs": ["./node_modules/.bin/jest", "-i", "--env", "jest-environment-node-debug"],
"runtimeArgs": ["./node_modules/.bin/jest", "-i"],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "internalConsole",
"sourceMaps": true
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/distribution"]
}
]
}
35 changes: 28 additions & 7 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,37 @@

### Master

- [WIP] Support [a vm2](https://github.com/patriksimek/vm2) based Dangerfile runner as an alternative to the
jest infrastructure. There are two main reasons for this:
### 2.0.0-alpha.1

* I haven't been able to completely understand how Jest's internals work around all of the code-eval and pre-requisite setup, which has made it hard to work on some more complex Peril features
* VM2 supports async code inside a Dangerfile
- Support [a vm2](https://github.com/patriksimek/vm2) based Dangerfile runner as an alternative to the
jest infrastructure. There are a few main reasons for this:

The massive downside to this is that Danger now has to build support for transpiling via Babel, or
from TypeScript unlike before, where it was a freebie inside Jest. This means that a Dangerfile which used
to "just work" with no config may not. Thus, a breaking major semver.
* I haven't been able to completely understand how Jest's internals work around all of the code-eval and
pre-requisite setup, which has made it hard to work on some more complex Peril features.

* Jest releases are every few months, personally I love this as a user of Jest, as an API consumer
it can be difficult to get changes shipped.

* The fact that both Danger/Jest make runtime changes means that you need to update them together

* I have commit access to vm2, so getting changes done is easy

I like to think of it as having gone from Jest's runner which is a massive toolbox, to vm2 which is a tiny
toolbox where I'll have to add a bunch of new tools to get everything working.

The *massive downside* to this is that Danger now has to have support for transpiling via Babel, or
from TypeScript unlike before, where it was a freebie inside Jest. Jest handled this so well. This means that a
Dangerfile which used to "just work" with no config may not. Thus, IMO, this is a breaking major semver.

Is it likely that you need to make any changes? So far, it seems probably not. At least all of the tests with
Dangerfiles original from the older Jest runner pass with the new version.

This is an alpha release, because it's knowingly shipped with some breakages around babel support, specifically:

* Babel parsing of relative imports in a Dangerfile aren't working
* Some of the features which require the `regeneratorRuntime` to be set up aren't working yet

Those are blockers on a 2.0.0 release.

### 1.2.0

Expand Down
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "danger",
"version": "1.2.0",
"version": "2.0.0-alpha.1",
"description": "Unit tests for Team Culture",
"main": "distribution/danger.js",
"typings": "distribution/danger.d.ts",
Expand Down Expand Up @@ -68,7 +68,6 @@
"husky": "^0.14.0",
"in-publish": "^2.0.0",
"jest": "^20.0.4",
"jest-environment-node-debug": "^2.0.0",
"lint-staged": "^4.0.0",
"madge": "^2.0.0",
"prettier": "^1.5.3",
Expand All @@ -87,7 +86,6 @@
"debug": "^2.6.0",
"github": "^9.2.0",
"jest-config": "^20.0.0",
"jest-environment-node": "^20.0.0",
"jest-runtime": "^20.0.0",
"jsome": "^2.3.25",
"jsonpointer": "^4.0.1",
Expand All @@ -99,7 +97,7 @@
"parse-diff": "^0.4.0",
"parse-link-header": "^1.0.1",
"rfc6902": "^1.3.0",
"vm2": "orta/vm2#compilers",
"vm2": "patriksimek/vm2",
"voca": "^1.2.0"
},
"optionalDependencies": {}
Expand Down
93 changes: 91 additions & 2 deletions source/ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,24 @@ declare module "parse-link-header"
declare module "*/package.json"

declare module "vm2" {
/**
* Require options for a VM
*/
export interface VMRequire {
/** Array of allowed builtin modules, accepts ["*"] for all (default: none) */
builtin?: string[]
/*
* `host` (default) to require modules in host and proxy them to sandbox. `sandbox` to load, compile and
* require modules in sandbox. Builtin modules except `events` always required in host and proxied to sandbox
*/
context?: "host" | "sandbox"
external?: boolean
/** `true` or an array of allowed external modules (default: `false`) */
external?: boolean | string[]
/** Array of modules to be loaded into NodeVM on start. */
import?: string[]
/** Restricted path where local modules can be required (default: every path). */
root?: string
/** Collection of mock modules (both external or builtin). */
mock?: any
}

Expand All @@ -30,26 +42,103 @@ declare module "vm2" {
*/
type CompilerFunction = (code: string, filename: string) => string

/**
* Options for creating a NodeVM
*/
export interface VMOptions {
/**
* `javascript` (default) or `coffeescript` or custom compiler function (which receives the code, and it's filepath).
* The library expects you to have coffee-script pre-installed if the compiler is set to `coffeescript`.
*/
compiler?: "javascript" | "coffeescript" | CompilerFunction
/** VM's global object. */
sandbox?: any
/**
* Script timeout in milliseconds. Timeout is only effective on code you run through `run`.
* Timeout is NOT effective on any method returned by VM.
*/
timeout?: number
}

/**
* Options specific o
*/
export interface NodeVMOptions extends VMOptions {
/** `inherit` to enable console, `redirect` to redirect to events, `off` to disable console (default: `inherit`). */
console?: "inherit" | "redirect"
/** `true` or an object to enable `require` optionss (default: `false`). */
require?: true | VMRequire
/** `true` to enable VMs nesting (default: `false`). */
nesting?: boolean
/** `commonjs` (default) to wrap script into CommonJS wrapper, `none` to retrieve value returned by the script. */
wrapper?: "commonjs" | "none"
}

/**
* A VM with behavior more similar to running inside Node.
*/
export class NodeVM {
constructor(options?: NodeVMOptions)
/** Runs the code */
run(js: string, path: string): any
/** Runs the VMScript object */
run(script: VMScript): any

/** Freezes the object inside VM making it read-only. Not available for primitive values. */
freeze(object: any, name: string): any
/** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values. */
protect(object: any, name: string): any
/** Require a module in VM and return it's exports. */
require(module: string): any
}

/**
* VM is a simple sandbox, without `require` feature, to synchronously run an untrusted code.
* Only JavaScript built-in objects + Buffer are available. Scheduling functions
* (`setInterval`, `setTimeout` and `setImmediate`) are not available by default.
*/
export class VM {
constructor(options?: VMOptions)
run(js: string, path: string): any
/** Runs the code */
run(js: string): any
/** Runs the VMScript object */
run(script: VMScript): any
/** Freezes the object inside VM making it read-only. Not available for primitive values. */
freeze(object: any, name: string): any
/** Protects the object inside VM making impossible to set functions as it's properties. Not available for primitive values */
protect(object: any, name: string): any

/**
* Create NodeVM and run code inside it.
*
* @param {String} script Javascript code.
* @param {String} [filename] File name (used in stack traces only).
* @param {Object} [options] VM options.
*/
static code(script: string, filename: string, options: NodeVMOptions): NodeVM

/**
* Create NodeVM and run script from file inside it.
*
* @param {String} [filename] File name (used in stack traces only).
* @param {Object} [options] VM options.
*/
static file(filename: string, options: NodeVMOptions): NodeVM
}

/**
* You can increase performance by using pre-compiled scripts.
* The pre-compiled VMScript can be run later multiple times. It is important to note that the code is not bound
* to any VM (context); rather, it is bound before each run, just for that run.
*/
export class VMScript {
constructor(code: string, path: string)
/** Wraps the code */
wrap(prefix: string, postfix: string): VMScript
/** Compiles the code. If called multiple times, the code is only compiled once. */
compile(): any
}

/** Custom Error class */
export class VMError extends Error {}
}
2 changes: 1 addition & 1 deletion source/commands/danger-pr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ async function runDanger(source: FakeCI, platform: GitHub, file: string) {
const runtimeEnv = await exec.setupDanger()
const results = await runDangerfileEnvironment(file, runtimeEnv)
if (program["repl"]) {
openRepl(runtimeEnv.context)
openRepl(runtimeEnv.sandbox)
} else {
jsome(results)
}
Expand Down
3 changes: 0 additions & 3 deletions source/danger.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,6 @@ declare module "danger" {
*/
function markdown(message: MarkdownString): void

/** Typical console */
const console: Console

/**
* The root Danger object. This contains all of the metadata you
* will be looking for in order to generate useful rules.
Expand Down
4 changes: 0 additions & 4 deletions source/runner/Dangerfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ export interface DangerContext {
*/
markdown(message: MarkdownString): void

/** Typical console */
console: Console

/**
* The root Danger object. This contains all of the metadata you
* will be looking for in order to generate useful rules.
Expand Down Expand Up @@ -89,7 +86,6 @@ export function contextForDanger(dsl: DangerDSLType): DangerContext {
warn,
message,
markdown,
console,
results,
danger: dsl,
}
Expand Down

0 comments on commit 58dc72a

Please sign in to comment.