From 27e9e2f5be4c61cce36c0b3460e01e867b5613ea Mon Sep 17 00:00:00 2001 From: Jon Edvald Date: Sat, 12 May 2018 02:19:28 +0200 Subject: [PATCH] fix: version is now correctly set for plugin modules (#84) --- .gardenignore | 2 ++ .gitignore | 2 +- garden.yml | 7 +++++ gulpfile.ts | 40 ++++++++++++++++++++++---- package-lock.json | 28 +++++++++++++++++++ package.json | 1 + src/cli.ts | 10 ++++++- src/constants.ts | 1 + src/plugins/kubernetes/deployment.ts | 5 ---- src/types/module.ts | 42 +++++++++++++++++++++++++++- 10 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 .gardenignore create mode 100644 garden.yml diff --git a/.gardenignore b/.gardenignore new file mode 100644 index 00000000000..0c76a8cf09f --- /dev/null +++ b/.gardenignore @@ -0,0 +1,2 @@ +examples/ +test/ diff --git a/.gitignore b/.gitignore index e794b7199f5..48d07c78d3b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,7 @@ build/ coverage/ dist/ examples/**/app.yaml -*.js +gulpfile.js *.map src/**/*.js src/**/*.map diff --git a/garden.yml b/garden.yml new file mode 100644 index 00000000000..b1fdad37a54 --- /dev/null +++ b/garden.yml @@ -0,0 +1,7 @@ +project: + name: garden-framework + environments: + local: + providers: + container: {} + local-kubernetes: {} diff --git a/gulpfile.ts b/gulpfile.ts index 1ab4b71a663..2b846f70e4c 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -1,8 +1,16 @@ -import { spawn as _spawn, ChildProcess } from "child_process" -import { join } from "path" +import { + spawn as _spawn, + ChildProcess, +} from "child_process" +import { writeFileSync } from "fs" +import { + join, + relative, +} from "path" const gulp = require("gulp") const cached = require("gulp-cached") +const excludeGitIgnore = require("gulp-exclude-gitignore") // const debug = require("gulp-debug") // const exec = require("gulp-exec") const pegjs = require("gulp-pegjs") @@ -47,7 +55,6 @@ function spawn(cmd, args, cb) { child.stderr.on("data", (data) => output.push(data.toString())) child.on("exit", (code) => { - console.log(code) if (code !== 0) { console.log(output.join("")) die() @@ -65,6 +72,28 @@ function die() { process.exit(1) } +gulp.task("add-version-files", (cb) => { + const gardenBinPath = join(destDir, "src", "bin", "garden.js") + const proc = _spawn("node", [gardenBinPath, "scan", "--output=json"]) + + proc.on("error", err => cb(err)) + + let output = "" + proc.stdout.on("data", d => output += d) + + proc.on("close", () => { + const results = JSON.parse(output) + + for (const module of Object.values(results.result)) { + const relPath = relative(__dirname, module.path) + const versionFilePath = join(__dirname, destDir, relPath, ".garden-version") + writeFileSync(versionFilePath, JSON.stringify(module.version)) + } + + cb() + }) +}) + gulp.task("check-licenses", (cb) => spawn("./bin/check-licenses", [], cb), ) @@ -85,12 +114,13 @@ gulp.task("pegjs-watch", () => gulp.task("static", () => { return gulp.src(staticFiles, { base: "./" }) + .pipe(excludeGitIgnore()) .pipe(cached("static")) .pipe(gulp.dest(destDir)) }) gulp.task("static-watch", () => { - return gulp.watch(staticFiles, gulp.parallel("static")) + return gulp.watch(staticFiles, gulp.series("static", "add-version-files")) }) gulp.task("tsc", () => @@ -154,7 +184,7 @@ gulp.task("tslint-watch", () => ) gulp.task("lint", gulp.parallel("check-licenses", "tslint", "tslint-tests", "tsfmt")) -gulp.task("build", gulp.parallel("pegjs", "static", "tsc")) +gulp.task("build", gulp.series(gulp.parallel("pegjs", "static", "tsc"), "add-version-files")) gulp.task("dist", gulp.series((done) => { setDestDir("dist"); done() }, "lint", "build")) gulp.task("test", gulp.parallel("build", "lint", "mocha")) gulp.task("watch", diff --git a/package-lock.json b/package-lock.json index 48b58d6b9c5..e8d225d4a4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4162,6 +4162,15 @@ "tildify": "^1.1.2" } }, + "gulp-exclude-gitignore": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gulp-exclude-gitignore/-/gulp-exclude-gitignore-1.2.0.tgz", + "integrity": "sha512-J3LCmz9C1UU1pxf5Npx6SNc5o9YQptyc9IHaqLiBlihZmg44jaaTplWUZ0JPQkMdOTae0YgEDvT9TKlUWDSMUA==", + "dev": true, + "requires": { + "gulp-ignore": "^2.0.2" + } + }, "gulp-exec": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/gulp-exec/-/gulp-exec-3.0.1.tgz", @@ -4173,6 +4182,25 @@ "through2": "^2.0.3" } }, + "gulp-ignore": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gulp-ignore/-/gulp-ignore-2.0.2.tgz", + "integrity": "sha1-XC6ioKRALgq0orzRLv2SlTRNePI=", + "dev": true, + "requires": { + "gulp-match": "^1.0.3", + "through2": "^2.0.1" + } + }, + "gulp-match": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz", + "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=", + "dev": true, + "requires": { + "minimatch": "^3.0.3" + } + }, "gulp-pegjs": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/gulp-pegjs/-/gulp-pegjs-0.1.0.tgz", diff --git a/package.json b/package.json index 365f4ec9299..6a18a47accf 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "gulp": "^4.0.0", "gulp-cached": "^1.1.1", "gulp-debug": "^3.2.0", + "gulp-exclude-gitignore": "^1.2.0", "gulp-exec": "^3.0.1", "gulp-pegjs": "^0.1.0", "gulp-sourcemaps": "^2.6.4", diff --git a/src/cli.ts b/src/cli.ts index 4067991fa3c..d17231621a9 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -11,7 +11,11 @@ import * as sywac from "sywac" import chalk from "chalk" import { ScanCommand } from "./commands/scan" import { DeepPrimitiveMap } from "./types/common" -import { enumToArray, shutdown } from "./util" +import { + enumToArray, + shutdown, + sleep, +} from "./util" import { merge, intersection, reduce } from "lodash" import { BooleanParameter, @@ -314,6 +318,8 @@ export class GardenCli { if (output && result !== undefined) { const renderer = OUTPUT_RENDERERS[output] console.log(renderer({ success: true, result })) + // Note: this circumvents an issue where the process exits before the output is fully flushed + await sleep(100) } return result @@ -325,6 +331,8 @@ export class GardenCli { if (output) { const renderer = OUTPUT_RENDERERS[output] console.error(renderer(result)) + // Note: this circumvents an issue where the process exits before the output is fully flushed + await sleep(100) } return result diff --git a/src/constants.ts b/src/constants.ts index a1aa5eff619..eeaa17b9848 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -11,6 +11,7 @@ import { resolve } from "path" export const MODULE_CONFIG_FILENAME = "garden.yml" export const STATIC_DIR = resolve(__dirname, "..", "static") export const GARDEN_DIR_NAME = ".garden" +export const GARDEN_VERSIONFILE_NAME = ".garden-version" export const DEFAULT_NAMESPACE = "default" export const DEFAULT_PORT_PROTOCOL = "TCP" diff --git a/src/plugins/kubernetes/deployment.ts b/src/plugins/kubernetes/deployment.ts index dde22fd2bbf..e3f091bb876 100644 --- a/src/plugins/kubernetes/deployment.ts +++ b/src/plugins/kubernetes/deployment.ts @@ -122,11 +122,6 @@ export async function createDeployment(service: ContainerService, serviceContext const env: KubeEnvVar[] = toPairs(envVars).map(([name, value]) => ({ name, value: value + "" })) // expose some metadata to the container - env.push({ - name: "GARDEN_VERSION", - value: versionString, - }) - env.push({ name: "POD_NAME", valueFrom: { fieldRef: { fieldPath: "metadata.name" } }, diff --git a/src/types/module.ts b/src/types/module.ts index fb00fc8afb8..a736b8e2151 100644 --- a/src/types/module.ts +++ b/src/types/module.ts @@ -6,12 +6,23 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import { + existsSync, + readFileSync, +} from "fs" import * as Joi from "joi" +import { GARDEN_VERSIONFILE_NAME } from "../constants" import { ServiceMap } from "../garden" import { PluginContext } from "../plugin-context" import { DeployTask } from "../tasks/deploy" import { TestTask } from "../tasks/test" -import { identifierRegex, joiIdentifier, joiVariables, PrimitiveMap } from "./common" +import { + identifierRegex, + joiIdentifier, + joiVariables, + PrimitiveMap, + validate, +} from "./common" import { ConfigurationError } from "../exceptions" import Bluebird = require("bluebird") import { @@ -27,6 +38,7 @@ import { import { resolveTemplateStrings, TemplateStringContext } from "../template-string" import { Memoize } from "typescript-memoize" import { TreeVersion } from "../vcs/base" +import { join } from "path" export interface BuildCopySpec { source: string @@ -62,6 +74,12 @@ export interface TestConfig { [group: string]: TestSpec } +const versionFileSchema = Joi.object().keys({ + versionString: Joi.string().required(), + latestCommit: Joi.string().required(), + dirtyTimestamp: Joi.number().allow(null).required(), +}) + export interface ModuleConfig { allowPush: boolean build: BuildConfig @@ -109,6 +127,28 @@ export class Module { } async getVersion(): Promise { + const versionFilePath = join(this.path, GARDEN_VERSIONFILE_NAME) + + if (existsSync(versionFilePath)) { + // this is used internally to specify version outside of source control + const versionFileContents = readFileSync(versionFilePath).toString().trim() + + if (!!versionFileContents) { + try { + return validate(JSON.parse(versionFileContents), versionFileSchema) + } catch (err) { + throw new ConfigurationError( + `Unable to parse ${GARDEN_VERSIONFILE_NAME} as valid version file in module directory ${this.path}`, + { + modulePath: this.path, + versionFilePath, + versionFileContents, + }, + ) + } + } + } + const treeVersion = await this.ctx.vcs.getTreeVersion([this.path]) const versionChain: TreeVersion[] = await Bluebird.map(