diff --git a/.wiby.json b/.wiby.json index 515fba3..16938d5 100644 --- a/.wiby.json +++ b/.wiby.json @@ -2,15 +2,18 @@ "dependents": [ { "repository": "https://github.com/wiby-test/partial", - "pullRequest": false + "pullRequest": false, + "mode": "download" }, { "repository": "git://github.com/wiby-test/fail", - "pullRequest": false + "pullRequest": false, + "mode": "download" }, { "repository": "git+https://github.com/wiby-test/pass", - "pullRequest": true + "pullRequest": true, + "mode": "download" } ] } diff --git a/bin/commands/test.js b/bin/commands/test.js index 1e6ce03..c79fdfa 100644 --- a/bin/commands/test.js +++ b/bin/commands/test.js @@ -20,6 +20,12 @@ exports.builder = (yargs) => yargs desc: 'Test against a specific commit or branch', type: 'string' }) + .option('mode', { + desc: 'Choose the mode in which the package will be tested', + type: 'string', + choices: ['download', 'pull-request'], + default: 'pull-request' + }) .option('config', { desc: 'Path to the configuration file. By default it will try to load the configuration from the first file it finds in the current working directory: `.wiby.json`, `.wiby.js`', type: 'string' @@ -28,7 +34,7 @@ exports.builder = (yargs) => yargs exports.handler = (params) => { const config = params.dependent ? { - dependents: [{ repository: params.dependent, pullRequest: !!params['pull-request'], sha: params.sha || 'HEAD' }] + dependents: [{ repository: params.dependent, pullRequest: !!params['pull-request'], sha: params.sha || 'HEAD', mode: params.mode || 'pull-request' }] } : wiby.validate({ config: params.config }) diff --git a/lib/config.js b/lib/config.js index f996a42..044c0f7 100644 --- a/lib/config.js +++ b/lib/config.js @@ -15,7 +15,9 @@ const dependentSchema = joi.object({ ] }), pullRequest: joi.boolean().optional(), - sha: joi.string().optional().default('HEAD') + sha: joi.string().optional().default('HEAD'), + mode: joi.string().valid('pull-request', 'download').optional().default('pull-request') + // TODO: add option for modify the test script }).unknown(false) exports.schema = joi.object({ diff --git a/lib/test.js b/lib/test.js index ef69dc5..057f4ba 100644 --- a/lib/test.js +++ b/lib/test.js @@ -3,8 +3,12 @@ const context = require('./context') const github = require('./github') const gitURLParse = require('git-url-parse') +const exec = require('execa').execa const logger = require('./logger') const { ensureGithubToken } = require('./utils') +const tmp = require('tmp') +const { cp } = require('fs/promises') +const path = require('path') // setup logger namespace const testCommandNamespace = 'wiby:test' @@ -23,19 +27,58 @@ module.exports = async function ({ dependents }) { const parentDependencyLink = await context.getDependencyLink(parentRepositoryInfo.owner, parentRepositoryInfo.name, parentBranchName) debug('Commit URL to test:', parentDependencyLink) - for (const { repository: url, pullRequest, sha } of dependents) { + for (let { repository: url, pullRequest, sha, mode } of dependents) { const dependentRepositoryInfo = gitURLParse(url) - const dependentPkgJson = await github.getPackageJson(dependentRepositoryInfo.owner, dependentRepositoryInfo.name, sha) - debug(`Dependent module: ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}, sha ${sha}`) - if (!context.checkDependentUsesParent(parentPkgJSON.name, dependentPkgJson)) { - throw new Error(`${parentRepositoryInfo.owner}/${parentPkgJSON.name} not found in the package.json of ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}`) - } + if (mode === 'download') { + debug('Generating tarball') + + await exec('npm', ['pack']) + + const { name: tmpDir } = tmp.dirSync() + + debug(`Temporary directory: ${tmpDir}`) + + debug(`Copying package to ${tmpDir}`) + + cp(`${parentPkgJSON.name}-${parentPkgJSON.version}.tgz`, path.join(tmpDir, `${parentPkgJSON.name}-${parentPkgJSON.version}.tgz`)) + + if (url.startsWith('git+http')) { + url = url.replace('git+http', 'http') + } else if (url.startsWith('git://')) { + url = url.replace('git://', 'http://') + } + + debug(`Cloning dependent repository ${url} into ${tmpDir}`) + + await exec('git', ['clone', '--depth=1', url, tmpDir]) + + debug(`Changing directory to ${tmpDir}`) + process.chdir(tmpDir) + + debug(`Installing package from ${parentPkgJSON.name}-${parentPkgJSON.version}.tgz`) + await exec('npm', ['install', `${parentPkgJSON.name}-${parentPkgJSON.version}.tgz`]) + + try { + debug('Running tests') + + await exec('npm', ['run', 'test']) + } catch (error) { + // catch the error and report it + } + } else { + const dependentPkgJson = await github.getPackageJson(dependentRepositoryInfo.owner, dependentRepositoryInfo.name, sha) + debug(`Dependent module: ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}, sha ${sha}`) + + if (!context.checkDependentUsesParent(parentPkgJSON.name, dependentPkgJson)) { + throw new Error(`${parentRepositoryInfo.owner}/${parentPkgJSON.name} not found in the package.json of ${dependentRepositoryInfo.owner}/${dependentRepositoryInfo.name}`) + } - const patchedPackageJSON = applyPatch(parentDependencyLink, parentPkgJSON.name, dependentPkgJson, parentPkgJSON.name) - await pushPatch(patchedPackageJSON, dependentRepositoryInfo.owner, dependentRepositoryInfo.name, parentPkgJSON.name, parentBranchName, sha) - if (pullRequest) { - await createPR(dependentRepositoryInfo.owner, dependentRepositoryInfo.name, parentBranchName, parentDependencyLink) + const patchedPackageJSON = applyPatch(parentDependencyLink, parentPkgJSON.name, dependentPkgJson, parentPkgJSON.name) + await pushPatch(patchedPackageJSON, dependentRepositoryInfo.owner, dependentRepositoryInfo.name, parentPkgJSON.name, parentBranchName, sha) + if (pullRequest) { + await createPR(dependentRepositoryInfo.owner, dependentRepositoryInfo.name, parentBranchName, parentDependencyLink) + } } } } diff --git a/package.json b/package.json index 879bf60..6c52a7b 100644 --- a/package.json +++ b/package.json @@ -34,17 +34,18 @@ "colors": "1.4.0", "debug": "^4.3.1", "dotenv": "^16.0.0", + "execa": "^9.6.0", "git-url-parse": "^11.1.2", "joi": "^17.2.1", "simple-git": "~3.15.0", + "tmp": "^0.2.1", "yargs": "^17.0.0" }, "devDependencies": { "nock": "^13.0.3", "semver": "^7.7.1", "standard": "^16.0.0", - "tap": "^16.0.0", - "tmp": "^0.2.1" + "tap": "^16.0.0" }, "standard": { "ignore": [ diff --git a/test/config.js b/test/config.js index 140f499..5c62c0b 100644 --- a/test/config.js +++ b/test/config.js @@ -36,17 +36,20 @@ tap.test('config validation', async (tap) => { { repository: 'https://github.com/wiby-test/partial', pullRequest: false, - sha: 'HEAD' + sha: 'HEAD', + mode: 'pull-request' }, { repository: 'git://github.com/wiby-test/fail', pullRequest: false, - sha: 'HEAD' + sha: 'HEAD', + mode: 'pull-request' }, { repository: 'git+https://github.com/wiby-test/pass', pullRequest: true, - sha: 'HEAD' + sha: 'HEAD', + mode: 'pull-request' } ] })