Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "makeomatic",
"rules": {
"no-unused-expressions": 0
"no-unused-expressions": 0,
"object-curly-newline": 0
}
}
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit $1
1 change: 1 addition & 0 deletions git-hooks/prepare-commit-msg → .husky/prepare-commit-msg
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

case "$2,$3" in
merge,)
Expand Down
7 changes: 5 additions & 2 deletions .mdeprc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"test_framework": "jest --coverage --coverageDirectory <coverageDirectory> --runTestsByPath --runInBand",
"tests": "__tests__/*.js",
"auto_compose": true,
"node": "14",
"node": "16",
"tester_flavour": "chrome-tester",
"services": [
"redisSentinel",
Expand All @@ -22,5 +22,8 @@
"DEBUG": "${DEBUG:-''}"
}
}
}
},
"arbitrary_exec": [
"apk add git"
]
}
75 changes: 58 additions & 17 deletions __tests__/install.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@
const { directory } = require('tempy');
const { resolve } = require('path');
const { promisify } = require('util');
const set = require('lodash.set');
const stripEOF = require('strip-final-newline');
const fs = require('fs');
const fs = require('fs/promises');
const execFile = promisify(require('child_process').execFile);

const rm = promisify(fs.unlink);
const stat = promisify(fs.stat);
const writeFile = promisify(fs.writeFile);
const readFile = promisify(fs.readFile);

describe('test installing the package', () => {
const kFilename = 'deploy.tgz';
const cwd = process.cwd();
const tarball = resolve(cwd, kFilename);
const tmpDir = directory();

beforeAll(async () => {
await execFile('yarn', ['cache', 'clean']);
Expand All @@ -25,10 +20,13 @@ describe('test installing the package', () => {
});

describe('local install', () => {
const tmpDir = directory();

beforeAll(async () => {
console.info('changing to %s', tmpDir);
process.chdir(tmpDir);
await execFile('yarn', ['init', '-yp']);
await execFile('git', ['init']);
});

test('is able to install package locally', async () => {
Expand All @@ -43,33 +41,76 @@ describe('test installing the package', () => {
test('package.json enhanced', async () => {
const pkg = require(`${tmpDir}/package.json`); // eslint-disable-line import/no-dynamic-require
expect(pkg.scripts['semantic-release']).toBeDefined();
expect(pkg.husky.hooks['commit-msg']).toBeDefined();
expect(pkg.husky.hooks['prepare-commit-msg']).toBeDefined();
expect(pkg.husky).toBeUndefined();
});

test('.husky create', async () => {
expect((await fs.stat('.husky')).isDirectory()).toBe(true);
expect((await fs.stat('.husky/_/husky.sh')).isFile()).toBe(true);
expect((await fs.stat('.husky/commit-msg')).isFile()).toBe(true);
expect((await fs.stat('.husky/prepare-commit-msg')).isFile()).toBe(true);
});

test('releaserc & commitlint copied over', async () => {
expect((await stat('.releaserc.json')).isFile()).toBe(true);
expect((await stat('.commitlintrc.js')).isFile()).toBe(true);
expect((await fs.stat('.releaserc.json')).isFile()).toBe(true);
expect((await fs.stat('.commitlintrc.js')).isFile()).toBe(true);
});

test('on reinstall doesnt overwrite existing .releaserc.js(on)', async () => {
expect.assertions(1);

await writeFile('.releaserc.json', 'overwrite');
await fs.writeFile('.releaserc.json', 'overwrite');
const { stderr } = await execFile('yarn', ['add', tarball]);
console.info(stderr);
await expect(readFile('.releaserc.json', 'utf8')).resolves.toBe('overwrite');
await expect(fs.readFile('.releaserc.json', 'utf8')).resolves.toBe('overwrite');
}, 240000);

test('on reinstall doesnt overwrite existing .commitlintrc.js', async () => {
expect.assertions(1);

await writeFile('.commitlintrc.js', 'overwrite');
await fs.writeFile('.commitlintrc.js', 'overwrite');
await execFile('yarn', ['add', tarball]);
await expect(readFile('.commitlintrc.js', 'utf8')).resolves.toBe('overwrite');
await expect(fs.readFile('.commitlintrc.js', 'utf8')).resolves.toBe('overwrite');
}, 240000);
});

describe('local install (husky migration)', () => {
const tmpDir = directory();

beforeAll(async () => {
console.info('changing to %s', tmpDir);
process.chdir(tmpDir);
await execFile('yarn', ['init', '-yp']);
await execFile('git', ['init']);

const pkgName = `${tmpDir}/package.json`;
const pkg = JSON.parse(await fs.readFile(pkgName));
set(pkg, 'husky.hooks.commit-msg', 'commitlint -e $HUSKY_GIT_PARAMS');
await fs.writeFile(pkgName, JSON.stringify(pkg, null, 2));
});

test('is able to install package locally', async () => {
await execFile('yarn', ['add', tarball]);
}, 240000);

test('package.json enhanced, no husky', async () => {
const pkg = JSON.parse(await fs.readFile(`${tmpDir}/package.json`));
expect(pkg.husky).toBeUndefined();
});

test('.husky files present', async () => {
expect((await fs.stat('.husky')).isDirectory()).toBe(true);
expect((await fs.stat('.husky/_/husky.sh')).isFile()).toBe(true);
expect((await fs.stat('.husky/commit-msg')).isFile()).toBe(true);
expect((await fs.stat('.husky/prepare-commit-msg')).isFile()).toBe(true);
});

test('.husky files content sane', async () => {
const contents = await fs.readFile('.husky/commit-msg', { encoding: 'utf8' });
expect(contents).toContain('npx --no-install commitlint --edit $1');
});
});

describe('installs globally', () => {
test('is able to install package globally', async () => {
await execFile('yarn', ['global', 'add', tarball]);
Expand All @@ -78,13 +119,13 @@ describe('test installing the package', () => {
test('returns current node version in module', async () => {
process.chdir(cwd);
const { stdout } = await execFile('mdep', ['get-config', '--path', 'node']);
expect(stripEOF(stdout)).toBe('14');
expect(stripEOF(stdout)).toBe('16');
});
});

afterAll(async () => {
try {
await rm(kFilename);
await fs.rm(kFilename);
} catch (e) {
process.stderr.write(`nothing to cleanup ~ ${kFilename}\n`);
}
Expand Down
25 changes: 21 additions & 4 deletions bin/cmds/test_cmds/auto-compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,23 @@ exports.handler = (argv) => {
compose.version = argv.acv;
compose.networks = {};
compose.services = {};
compose.volumes = {};

if (argv.isMutagen) {
compose.volumes['makeomatic-deploy-code'] = {};
compose['x-mutagen'] = {
sync: {
defaults: {
ignore: { vcs: true },
mode: 'two-way-resolved',
},
code: {
alpha: process.cwd(),
beta: 'volume://makeomatic-deploy-code',
},
},
};
}

// Identification
if (Array.isArray(argv.services) && argv.services.length) {
Expand Down Expand Up @@ -66,7 +83,7 @@ function tester(compose, argv) {
image: argv.tester_image || `makeomatic/node:${argv.node}-${argv.tester_flavour}`,
hostname: 'tester',
working_dir: '/src',
volumes: ['${PWD}:/src'],
volumes: [argv.isMutagen ? 'makeomatic-deploy-code:/src' : '${PWD}:/src'],
environment: {
NODE_ENV: 'test',
},
Expand Down Expand Up @@ -105,7 +122,7 @@ function redisSentinel(compose, argv) {

function postgres(compose, argv) {
compose.services.postgres = merge({
image: 'postgres:12-alpine',
image: 'postgres:14-alpine',
hostname: 'postgres',
environment: {
POSTGRES_HOST_AUTH_METHOD: 'trust',
Expand All @@ -115,14 +132,14 @@ function postgres(compose, argv) {

function rabbitmq(compose, argv) {
compose.services.rabbitmq = merge({
image: 'rabbitmq:3.7.8-management-alpine',
image: 'rabbitmq:3-management-alpine',
hostname: 'rabbitmq',
}, argv.extras.rabbitmq);
}

function elasticsearch(compose, argv) {
compose.services.elasticsearch = merge({
image: 'elasticsearch:7.11.1',
image: 'elasticsearch:7.14.2',
hostname: 'elasticsearch',
expose: [
'9200',
Expand Down
52 changes: 12 additions & 40 deletions bin/cmds/test_cmds/compose.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
/**
* Installs compose
* @type {String}
*/

const npmPath = require('npm-path');
const path = require('path');
const onDeath = require('death')({ SIGHUP: true, exit: true });
const {
exec, echo, which, exit, mkdir, chmod, ShellString,
} = require('shelljs');
const { exec, echo, which, ShellString } = require('shelljs');

const isWin = process.platform === 'win32';

Expand All @@ -18,37 +10,17 @@ exports.handler = (argv) => {
npmPath.set();

// verify if we have compose or not
let compose = which('docker-compose');
const version = compose && exec(`"${compose}" --version`).stdout.match(/\d+\.\d+\.\d+/)[0];

// compose not found - install
if (compose === null || (argv.dcf && version !== argv.dcv)) {
if (compose === null) {
echo(`docker-compose was not found on the system, installing v${argv.dcv} into ./node_modules/.bin`);
} else {
echo(`docker-compose of ${version} was found at ${compose}, but force install provided, updating`);
}

// creating dir to make sure it exists
mkdir('./node_modules/.bin');

const distribution = exec('uname -s').stdout.trim();
const arch = exec('uname -m').stdout.trim();
const link = `https://github.com/docker/compose/releases/download/${argv.dcv}/docker-compose-${distribution}-${arch}`;
const curl = exec(`curl -L "${link}" -o ./node_modules/.bin/docker-compose`);

if (curl.code !== 0) {
echo(`failed to install docker-compose: ${curl.stderr}`);
exit(1);
}

compose = ShellString(path.resolve(process.cwd(), './node_modules/.bin/docker-compose'));
chmod('+x', compose);
}

const docker = which('docker');
const dockerComposeBin = which('docker-compose');
const mutagen = which('mutagen-compose');
const compose = mutagen || dockerComposeBin || `"${docker}" compose`;
const originalDockerCompose = argv.docker_compose;
const dockerComposeFiles = [];

if (mutagen) {
argv.isMutagen = true;
}

if (argv.docker_compose_multi.length > 0) {
dockerComposeFiles.push(...argv.docker_compose_multi);
}
Expand All @@ -71,7 +43,7 @@ exports.handler = (argv) => {
const composeFiles = dockerComposeFiles.map((x) => `-f ${x}`).join(' ');

// add link to compose file
argv.compose = ShellString(`"${compose}" ${composeFiles}`);
argv.compose = ShellString(`${compose} ${composeFiles}`);

function stopDocker(signal, code) {
const dockerCompose = argv.compose;
Expand All @@ -83,7 +55,7 @@ exports.handler = (argv) => {

if (argv.no_cleanup !== true) {
echo(`\nAutomatically cleaning up after ${signal}\n`);
exec(`${dockerCompose} down; true`);
exec(`${dockerCompose} down -v --remove-orphans; true`);

if (argv.auto_compose) {
const deleteCmd = (isWin ? 'del ' : 'rm ') + argv.docker_compose;
Expand All @@ -94,7 +66,7 @@ exports.handler = (argv) => {
// force exit now
if (signal === 'exit') process.exit(code || 0);
} else {
echo(`\nLocal environment detected.\nTo stop containers write:\n\n${dockerCompose} down;\n`);
echo(`\nLocal environment detected.\nTo stop containers write:\n\n${dockerCompose} down -v --remove-orphans;\n`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion bin/cmds/test_cmds/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ exports.handler = async (argv) => {
echo('failed to get container id. Exit 128');
exit(128);
}
const container = containerData.stdout.trim();
const container = containerData.stdout.trim().split('\n').pop();

// easy way to wait for containers, can do improved detection, but it's not generic
if (argv.rebuild.length > 0) {
Expand Down
Loading