Skip to content

Commit

Permalink
refactor: pull conftest plugins out of core package
Browse files Browse the repository at this point in the history
  • Loading branch information
edvald committed Aug 31, 2020
1 parent 469ca7d commit 6f4814e
Show file tree
Hide file tree
Showing 72 changed files with 4,592 additions and 204 deletions.
68 changes: 25 additions & 43 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,36 +64,23 @@ commands:
description: |
Installs npm packages for root, core, and dashboard and loads and saves the caches as appropriate
steps:
# See https://github.com/circleci/circleci-docs/issues/3933
- run:
name: Combine package-lock.json files to single file
command: lerna list -p -a | awk -F packages '{printf "\"packages%s/package-lock.json\" ", $2}' | xargs cat > combined-package-lock.json
- restore_cache:
keys:
- root-v4-{{ checksum "package-lock.json" }}
- restore_cache:
keys:
- cli-v4-{{ checksum "cli/package-lock.json" }}
- restore_cache:
keys:
- core-v4-{{ checksum "core/package-lock.json" }}
- restore_cache:
keys:
- dashboard-v4-{{ checksum "dashboard/package-lock.json" }}

# only install root dependencies if node_modules wasn't cached
- run: if [ ! -d "node_modules" ]; then npm ci; fi
- npm-v4-{{ checksum "package-lock.json" }}-{{ checksum "combined-package-lock.json" }}
- npm-v4-{{ checksum "package-lock.json" }}
- npm-v4

- run: npm install
- run: npm run bootstrap

- save_cache:
paths: [node_modules]
key: root-v4-{{ checksum "package-lock.json" }}
- save_cache:
paths: [cli/node_modules]
key: cli-v4-{{ checksum "cli/package-lock.json" }}
- save_cache:
paths: [core/node_modules]
key: core-v4-{{ checksum "core/package-lock.json" }}
- save_cache:
paths: [dashboard/node_modules]
key: dashboard-v4-{{ checksum "dashboard/package-lock.json" }}
key: root-v4-{{ checksum "package-lock.json" }}-{{ checksum "combined-package-lock.json" }}
paths:
- ~/.npm

install_kubectl:
description: Install kubectl
Expand Down Expand Up @@ -204,6 +191,9 @@ jobs:
- core/build/
- dashboard/build/
- static/
# TODO: see if we can make this somewhat more specific
- sdk/
- plugins/
build-dist:
<<: *node-config
steps:
Expand All @@ -226,7 +216,7 @@ jobs:
- run:
name: lint
command: npm run lint
test-service:
test-framework:
<<: *node-config
steps:
- checkout
Expand All @@ -240,10 +230,9 @@ jobs:
git config --global user.name "Garden CI"
git config --global user.email "[email protected]"
- run:
name: test
name: Unit test framework components
command: |
cd core
npm test
npm test:framework:unit
environment:
CHOKIDAR_USEPOLLING: "1"
# (not used atm)
Expand Down Expand Up @@ -295,17 +284,6 @@ jobs:
name: Cleanup
command: kubectl delete --wait=false $(kubectl get ns -o name | grep testing-$CIRCLE_BUILD_NUM) || true
when: always
test-dashboard:
<<: *node-config
steps:
- checkout
- npm_install
- *attach-workspace
- run:
name: Test dashboard
command: |
cd dashboard
npm test
build-docker:
<<: *node-config
steps:
Expand Down Expand Up @@ -416,7 +394,7 @@ jobs:
- setup_remote_docker:
docker_layer_caching: true
- checkout
# This is to copy the pre-build build output from test-service (this should be a different step)
# This is to copy the pre-built code from a previous step
- *attach-workspace
# TODO: use garden publish here
- deploy:
Expand Down Expand Up @@ -551,6 +529,9 @@ jobs:
# and back in to add the circleci user to the microk8s group.
# - We currently don't support in-cluster building on microk8s.
GARDEN_SKIP_TESTS="cluster-docker kaniko remote-only" sudo -E npm run integ -- -b
- run:
name: Plugin tests
command: npm run test:plugins
- run:
name: Deploy demo-project
command: sudo -E ./bin/garden deploy --root examples/demo-project --logger-type basic
Expand Down Expand Up @@ -600,6 +581,9 @@ jobs:
name: Integ tests
# Note: We skip tests that only work for remote environments
command: cd core && npm run integ-local -- -b
- run:
name: Plugin tests
command: npm run test:plugins
- run:
name: Deploy demo-project
command: sudo -E ./bin/garden deploy --root examples/demo-project
Expand Down Expand Up @@ -714,14 +698,12 @@ workflows:
<<: *only-internal-prs
context: docker
requires: [build-docker-gcloud]
- test-service:
- test-framework:
requires: [build]
- test-dist:
# Don't attempt to run dist tests for external PRs (they won't have access to the required keys)
<<: *only-internal-prs
requires: [build-dist]
- test-dashboard:
requires: [build]
- test-windows:
# Don't attempt to run dist tests for external PRs (they won't have access to the required keys)
<<: *only-internal-prs
Expand Down
20 changes: 20 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ discussion, pull requests and any type of feedback. We request that all contribu
adhere to the [Contributor Covenant](CODE_OF_CONDUCT.md) and work with us to make the collaboration and
community productive and fun for everyone :)

## Project structure

The project code is composed of several components, most of which are written in TypeScript. There's also a number of supporting scripts, documents, examples etc. Here is an overview of the top-level project folders:

| Name | Description |
| ---- | ----------- |
| `bin` | Executable commands, to use for development. _Note that you need to build the project before these work._ |
| `cli` | The Garden CLI package, which composes code from different packages into the final CLI executable. |
| `core` | The bulk of the Garden code and tests live here. |
| `dashboard` | The Garden web dashboard, which is bundled with the CLI. |
| `docs` | Markdown documentation, which is used to generate [docs.garden.io](https://docs.garden.io). _Note that the reference docs are auto-generated, and should not be edited by hand!._ |
| `examples` | Various Garden example projects. |
| `images` | Supporting container images, used by e.g. the `kubernetes` provider. |
| `plugins` | Plugins that are bundled with Garden. We are in the process of moving plugins out of `core` and into separate packages here. |
| `scripts` | Various scripts for builds, releases and development. |
| `sdk` | The `@garden-io/sdk` package, used for Garden plugin development. |
| `secrets` | Encrypted files, used for integ/e2e testing. Only accessible to Garden maintainers. |
| `static` | Static files that are bundled with the CLI. |
| `support` | Supporting files for development, builds, releases etc. |

## Setting up your development environment

### Step 1: Install Docker and Kubernetes
Expand Down
7 changes: 7 additions & 0 deletions cli/.mocharc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
reporter: spec
spec:
- build/test/setup.js
- build/test/**/*.js
timeout: 10000
watch-files:
- build/**/*.js
6 changes: 5 additions & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
"garden": "bin/garden"
},
"dependencies": {
"@garden-io/core": "0.12.2"
"@garden-io/core": "*",
"@garden-io/garden-conftest": "*",
"@garden-io/garden-conftest-container": "*",
"@garden-io/garden-conftest-kubernetes": "*"
},
"devDependencies": {
"@types/chai": "^4.2.12",
Expand Down Expand Up @@ -55,6 +58,7 @@
"fix-format": "prettier --write \"{src,test}/**/*.ts\"",
"generate-docs": "node ./build/src/generate-docs.js",
"lint": "tslint -p .",
"test": "mocha",
"tsc": "tsc -p .",
"watch": "npm run tsc -- -w"
},
Expand Down
23 changes: 19 additions & 4 deletions cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,23 @@ import { gardenEnv } from "@garden-io/core/build/src/constants"
import { getDefaultProfiler } from "@garden-io/core/build/src/util/profiling"
import { GardenProcess } from "@garden-io/core/build/src/db/entities/garden-process"
import { ensureConnected } from "@garden-io/core/build/src/db/connection"
import { GardenCli } from "@garden-io/core/build/src/cli/cli"
import { GardenCli, RunOutput } from "@garden-io/core/build/src/cli/cli"
import { GardenPlugin } from "@garden-io/core/build/src/types/plugin/plugin"

export async function runCli({ args, cli }: { args?: string[]; cli?: GardenCli } = {}): Promise<void> {
// These plugins are always registered
export const bundledPlugins = [
require("@garden-io/garden-conftest"),
require("@garden-io/garden-conftest-container"),
require("@garden-io/garden-conftest-kubernetes"),
].map((m) => m.gardenPlugin as GardenPlugin)

export async function runCli({
args,
cli,
exitOnError = true,
}: { args?: string[]; cli?: GardenCli; exitOnError?: boolean } = {}) {
let code = 0
let result: RunOutput | undefined = undefined

if (!args) {
args = process.argv.slice(2)
Expand All @@ -25,10 +38,10 @@ export async function runCli({ args, cli }: { args?: string[]; cli?: GardenCli }

try {
if (!cli) {
cli = new GardenCli()
cli = new GardenCli({ plugins: bundledPlugins })
}
// Note: We slice off the binary/script name from argv.
const result = await cli.run({ args, exitOnError: true, processRecord })
result = await cli.run({ args, exitOnError, processRecord })
code = result.code
} catch (err) {
// tslint:disable-next-line: no-console
Expand All @@ -44,4 +57,6 @@ export async function runCli({ args, cli }: { args?: string[]; cli?: GardenCli }

await shutdown(code)
}

return { cli, result }
}
3 changes: 2 additions & 1 deletion cli/src/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { resolve } from "path"
import { Logger } from "@garden-io/core/build/src/logger/logger"
import { LogLevel } from "@garden-io/core/build/src/logger/log-node"
import { GARDEN_CLI_ROOT } from "@garden-io/core/build/src/constants"
import { bundledPlugins } from "./cli"

require("source-map-support").install()

Expand All @@ -23,7 +24,7 @@ try {
})
} catch (_) {}

generateDocs(resolve(GARDEN_CLI_ROOT, "..", "docs"))
generateDocs(resolve(GARDEN_CLI_ROOT, "..", "docs"), bundledPlugins)
.then(() => {
// tslint:disable-next-line: no-console
console.log("Done!")
Expand Down
12 changes: 12 additions & 0 deletions cli/test/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright (C) 2018-2020 Garden Technologies, Inc. <[email protected]>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { join } from "path"
import { GARDEN_CLI_ROOT } from "@garden-io/core/build/src/constants"

export const testRoot = join(GARDEN_CLI_ROOT, "test")
10 changes: 10 additions & 0 deletions cli/test/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (C) 2018-2020 Garden Technologies, Inc. <[email protected]>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

// Borrow the basic test setup from core
require("@garden-io/core/build/test/setup")
6 changes: 6 additions & 0 deletions cli/test/test-projects/bundled-projects/project.garden.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Project
name: bundled-projects
providers:
- name: conftest
- name: conftest-container
- name: conftest-kubernetes
15 changes: 14 additions & 1 deletion cli/test/unit/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,33 @@

import { expect } from "chai"
import { find } from "lodash"
import { resolve } from "path"

import { runCli, bundledPlugins } from "../../../src/cli"
import { testRoot } from "../../helpers"

import { GardenCli } from "@garden-io/core/build/src/cli/cli"
import { projectRootA } from "@garden-io/core/build/test/helpers"
import { Command, CommandParams } from "@garden-io/core/build/src/commands/base"
import { GardenProcess } from "@garden-io/core/build/src/db/entities/garden-process"
import { ensureConnected } from "@garden-io/core/build/src/db/connection"
import { randomString } from "@garden-io/core/build/src/util/string"
import { runCli } from "../../../src/cli"

describe("runCli", () => {
before(async () => {
await ensureConnected()
})

it("should add bundled plugins", async () => {
const projectRoot = resolve(testRoot, "test-projects", "bundled-projects")
const { cli, result } = await runCli({ args: ["tools", "--root", projectRoot], exitOnError: false })

expect(cli!["plugins"]).to.eql(bundledPlugins)

const conftestTool = result?.result?.tools?.find((t) => t.pluginName === "conftest")
expect(conftestTool).to.exist
})

it("should register a GardenProcess entry and pass to cli.run()", (done) => {
class TestCommand extends Command {
name = randomString(10)
Expand Down
2 changes: 1 addition & 1 deletion core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@
"integ-remote": "GARDEN_INTEG_TEST_MODE=remote GARDEN_SKIP_TESTS=local-only mocha --opts test/mocha.integ.opts",
"e2e": "cd test/e2e && ../../../bin/garden test",
"e2e-project": "node build/test/e2e/e2e-project.js",
"test": "node_modules/.bin/mocha --opts test/mocha.opts",
"test": "mocha --opts test/mocha.opts",
"tsc": "tsc -p .",
"watch": "npm run tsc -- -w"
},
Expand Down
7 changes: 6 additions & 1 deletion core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { BufferedEventStream } from "../enterprise/buffered-event-stream"
import { makeEnterpriseContext } from "../enterprise/init"
import { GardenProcess } from "../db/entities/garden-process"
import { DashboardEventStream } from "../server/dashboard-event-stream"
import { GardenPlugin } from "../types/plugin/plugin"

export async function makeDummyGarden(root: string, gardenOpts: GardenOpts = {}) {
const environments = gardenOpts.environmentName
Expand Down Expand Up @@ -79,8 +80,11 @@ export interface RunOutput {
export class GardenCli {
private commands: { [key: string]: Command } = {}
private fileWritersInitialized: boolean = false
private plugins: GardenPlugin[]

constructor({ plugins }: { plugins?: GardenPlugin[] } = {}) {
this.plugins = plugins || []

constructor() {
const commands = sortBy(getAllCommands(), (c) => c.name)
commands.forEach((command) => this.addCommand(command))
}
Expand Down Expand Up @@ -204,6 +208,7 @@ ${renderCommands(commands)}
sessionId,
forceRefresh,
variables: parsedCliVars,
plugins: this.plugins,
}

let garden: Garden
Expand Down
5 changes: 3 additions & 2 deletions core/src/commands/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { printHeader, getTerminalWidth } from "../logger/util"
import { LoggerType } from "../logger/logger"
import { StringOption } from "../cli/params"
import { GardenModule } from "../types/module"
import stripAnsi from "strip-ansi"

const pluginArgs = {
plugin: new StringOption({
Expand Down Expand Up @@ -145,12 +146,12 @@ async function listPlugins(garden: Garden, log: LogEntry, pluginsToList: string[
return [` ${chalk.cyan(pluginName + " " + command.name)}`, command.description]
})

const maxCommandLength = max(rows.map((r) => r[0].length))!
const maxCommandLengthAnsi = max(rows.map((r) => r[0].length))!

log.info(
renderTable(rows, {
...tablePresets["no-borders"],
colWidths: [null, getTerminalWidth() - maxCommandLength],
colWidths: [null, getTerminalWidth() - maxCommandLengthAnsi],
})
)

Expand Down
Loading

0 comments on commit 6f4814e

Please sign in to comment.