-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib/test: add initial prototype for wiby --test
- Loading branch information
1 parent
9692bfb
commit a80429a
Showing
8 changed files
with
383 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,26 @@ | ||
#!/usr/bin/env node | ||
|
||
require('dotenv').config() | ||
const test = require('../lib/test') | ||
const result = require('../lib/result') | ||
|
||
if (process.argv[2] === 'test') { | ||
test() | ||
const args = require('yargs') | ||
.option('test', { | ||
alias: 't', | ||
describe: 'Test your dependents' | ||
}) | ||
.option('result', { | ||
alias: 'r', | ||
describe: 'Get the result of your tests' | ||
}) | ||
.argv | ||
|
||
if (args.test) { | ||
test(args.test) | ||
} | ||
|
||
if (process.argv[2] === 'result') { | ||
if (args.result) { | ||
result() | ||
} | ||
|
||
// Usage: wiby --test URL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
const { graphql } = require('@octokit/graphql') | ||
const { Octokit } = require('@octokit/rest') | ||
const octokit = new Octokit({ | ||
auth: process.env.GITHUB_TOKEN | ||
}) | ||
|
||
const graphqlWithAuth = graphql.defaults({ | ||
headers: { | ||
authorization: `token ${process.env.GITHUB_TOKEN}` | ||
} | ||
}) | ||
|
||
module.exports.getPackageJson = | ||
async function getPackageJson (owner, repo) { | ||
try { | ||
const resp = await graphqlWithAuth({ | ||
query: `query($owner: String!, $repo: String!) { | ||
repository(name: $repo, owner: $owner) { | ||
object(expression: "master:package.json") { | ||
... on Blob { | ||
text | ||
} | ||
} | ||
} | ||
}`, | ||
owner: owner, | ||
repo: repo | ||
}) | ||
return (JSON.parse(resp.repository.object.text)) | ||
} catch (err) { | ||
if (err.errors && err.errors[0].type === 'NOT_FOUND') { | ||
throw Error(`Could not find GitHub repository at https://www.github.com/${owner}/${repo}`) | ||
} else { | ||
throw err | ||
} | ||
} | ||
} | ||
|
||
module.exports.getPermissions = | ||
async function getPermissions (owner, repo) { | ||
try { | ||
const resp = await graphqlWithAuth({ | ||
query: `query($owner: String!, $repo: String!) { | ||
repository(name: $repo, owner: $owner) { | ||
viewerPermission | ||
} | ||
}`, | ||
owner: owner, | ||
repo: repo | ||
}) | ||
return resp.repository.viewerPermission | ||
} catch (err) { | ||
if (err.errors && err.errors[0].type === 'NOT_FOUND') { | ||
throw Error(`Could not find GitHub repository at https://www.github.com/${owner}/${repo}`) | ||
} else { | ||
throw err | ||
} | ||
} | ||
} | ||
|
||
module.exports.getShas = | ||
async function getShas (owner, repo) { | ||
const resp = await octokit.repos.listCommits({ | ||
owner, | ||
repo, | ||
per_page: 1 | ||
}) | ||
const headSha = resp.data[0].sha | ||
const treeSha = resp.data[0].commit.tree.sha | ||
// console.log(`lastSha: ${headSha} treeSha: ${treeSha}`) | ||
return [headSha, treeSha] | ||
} | ||
|
||
module.exports.createBlob = | ||
async function createBlob (owner, repo, file) { | ||
const { | ||
data: { sha: blobSha } | ||
} = await octokit.git.createBlob({ | ||
owner, | ||
repo, | ||
content: file, | ||
encoding: 'base64' | ||
}) | ||
return blobSha | ||
} | ||
|
||
module.exports.createTree = async function createTree (owner, repo, treeSha, blobSha) { | ||
const resp = await octokit.git.createTree({ | ||
owner, | ||
repo, | ||
base_tree: treeSha, | ||
tree: [ | ||
{ path: 'package.json', mode: '100644', sha: blobSha } | ||
], | ||
headers: { | ||
Accept: 'application/json' | ||
} | ||
}) | ||
const newTreeSha = resp.data.sha | ||
return newTreeSha | ||
} | ||
|
||
module.exports.createCommit = | ||
async function createCommit (owner, repo, message, newTreeSha, headSha) { | ||
const resp = await octokit.git.createCommit({ | ||
owner, | ||
repo, | ||
message: message, | ||
tree: newTreeSha, | ||
parents: [headSha] | ||
}) | ||
const commitSha = resp.data.sha | ||
return commitSha | ||
} | ||
|
||
module.exports.createBranch = | ||
async function createBranch (owner, repo, commitSha, branch) { | ||
await octokit.git.createRef({ | ||
owner, | ||
repo, | ||
sha: commitSha, | ||
ref: `refs/heads/${branch}` | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,107 @@ | ||
module.exports = () => { | ||
console.log('wiby test') | ||
const fs = require('fs') | ||
const fetch = require('node-fetch') | ||
const { promisify } = require('util') | ||
const github = require('./github') | ||
const readFileAsync = promisify(fs.readFile) | ||
|
||
module.exports = async function (url) { | ||
const dep = await getLocalPackageName() | ||
console.log('Got local package name: ', dep) | ||
const [org, repo] = getOrgRepo(url) | ||
console.log(`Got org: ${org} and repo: ${repo}`) | ||
const packageJSON = await github.getPackageJson(org, repo) | ||
if (!checkPackageInPackageJSON(dep, packageJSON)) { | ||
throw new Error('Dependency not found in package.json') | ||
} | ||
const patch = await getPatch(dep) | ||
console.log('Created patch: ', patch) | ||
const patchedPackageJSON = applyPatch(patch, dep, packageJSON) | ||
await pushPatch(patchedPackageJSON, org, repo, dep) | ||
} | ||
|
||
const getCommitHash = module.exports.getCommitHash = | ||
async function getCommitHash (owner, repo) { | ||
const headSha = (await github.getShas(owner, repo))[0] | ||
return headSha | ||
} | ||
|
||
const checkPackageInPackageJSON = module.exports.checkPackageInPackageJSON = | ||
function checkPackageInPackageJSON (dep, packageJSON) { | ||
return Object.prototype.hasOwnProperty.call(packageJSON.dependencies, dep) | ||
} | ||
|
||
const getOrgRepo = module.exports.getOrgRepo = | ||
function getOrgRepo (url) { | ||
const repoOrgArr = (url.split('github.com'))[1].split('/') | ||
const org = repoOrgArr[1] | ||
const repo = repoOrgArr[2] | ||
return [org, repo] | ||
} | ||
|
||
const getPatch = module.exports.getPatch = | ||
async function getPatch (dep, hash) { | ||
dep = dep || await getLocalPackageName() | ||
const [org, repo] = await getGitHubOrgRepo(dep) | ||
hash = hash || await getCommitHash(org, repo) | ||
const patch = `${org}/${repo}#${hash}` | ||
return patch | ||
} | ||
|
||
const getLocalPackageName = module.exports.getLocalPackageName = | ||
async function getLocalPackageName (pkgPath) { | ||
pkgPath = pkgPath || 'package.json' | ||
let pkg = await readFileAsync(pkgPath).catch((err) => { | ||
throw (err) | ||
}) | ||
pkg = JSON.parse(pkg) | ||
return pkg.name | ||
} | ||
|
||
const getGitHubOrgRepo = module.exports.getGitHubOrgRepo = | ||
async function getGitHubOrgRepo (dep) { | ||
const urlRegex = /github.com\/([^/])+\/[^/]+/g | ||
const resp = await fetchRegistryInfo(dep) | ||
let org, repo | ||
if (resp.repository && resp.repository.url) { | ||
let gitUrl = (resp.repository.url).match(urlRegex) | ||
if (gitUrl) { | ||
gitUrl = gitUrl[0].replace(/(\.git)/g, '') | ||
org = getOrgRepo(gitUrl)[0] | ||
repo = getOrgRepo(gitUrl)[1] | ||
} | ||
} | ||
if (!org && !repo) { | ||
org = 'undefined' | ||
repo = 'undefined' | ||
} | ||
return [org, repo] | ||
} | ||
|
||
const fetchRegistryInfo = module.exports.fetchRegistryInfo = | ||
async function fetchRegistryInfo (dep) { | ||
const resp = await fetch(`https://registry.npmjs.org/${dep}`) | ||
return resp.json() | ||
} | ||
|
||
const applyPatch = module.exports.applyPatch = | ||
function applyPatch (patch, dep, packageJSON) { | ||
if (!Object.prototype.hasOwnProperty.call(packageJSON.dependencies, dep)) { | ||
throw new Error('Dependency not found in package.json') | ||
} | ||
packageJSON.dependencies[dep] = patch | ||
return packageJSON | ||
} | ||
|
||
async function pushPatch (packageJSON, owner, repo, dep) { | ||
const file = JSON.stringify(packageJSON, null, 2) + '\n' // assumes package.json is using two spaces | ||
const encodedFile = Buffer.from(file).toString('base64') | ||
const message = `wiby: update ${dep}` | ||
const branch = `wiby-${dep}` | ||
|
||
const [headSha, treeSha] = await github.getShas(owner, repo) | ||
const blobSha = await github.createBlob(owner, repo, encodedFile) | ||
const newTreeSha = await github.createTree(owner, repo, treeSha, blobSha) | ||
const commitSha = await github.createCommit(owner, repo, message, newTreeSha, headSha) | ||
await github.createBranch(owner, repo, commitSha, branch) | ||
console.log(`Changes pushed to https://github.com/${owner}/${repo}/blob/${branch}/package.json`) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
module.exports.DEP_URL = 'https://github.com/andrewhughes101/do-you-pass' | ||
module.exports.PKGJSON = { | ||
name: 'do-you-pass', | ||
version: '1.0.0', | ||
description: 'Does i-should-pass pass?', | ||
main: 'index.js', | ||
scripts: { | ||
test: 'node test.js' | ||
}, | ||
author: 'Andrew Hughes', | ||
license: 'Apache-2.0', | ||
homepage: 'https://github.com/andrewhughes101/do-you-pass', | ||
repository: { | ||
type: 'git', | ||
url: 'https://github.com/andrewhughes101/do-you-pass.git' | ||
}, | ||
dependencies: { | ||
'i-should-pass': '^1.0.0' | ||
} | ||
} | ||
module.exports.PATCHED_PKGJSON = { | ||
name: 'do-you-pass', | ||
version: '1.0.0', | ||
description: 'Does i-should-pass pass?', | ||
main: 'index.js', | ||
scripts: { | ||
test: 'node test.js' | ||
}, | ||
author: 'Andrew Hughes', | ||
license: 'Apache-2.0', | ||
homepage: 'https://github.com/andrewhughes101/do-you-pass', | ||
repository: { | ||
type: 'git', | ||
url: 'https://github.com/andrewhughes101/do-you-pass.git' | ||
}, | ||
dependencies: { | ||
'i-should-pass': 'andrewhughes101/i-should-pass#ec218ed4d7bd085c4aa3d94c2f86a43470754816' | ||
} | ||
} | ||
module.exports.PATCH = 'andrewhughes101/i-should-pass#ec218ed4d7bd085c4aa3d94c2f86a43470754816' | ||
module.exports.PKG_NAME = 'i-should-pass' | ||
module.exports.PKG_REPO = 'i-should-pass' | ||
module.exports.PKG_ORG = 'andrewhughes101' | ||
module.exports.DEP_REPO = 'do-you-pass' | ||
module.exports.DEP_ORG = 'andrewhughes101' | ||
module.exports.PKG_HEAD_SHA = 'ec218ed4d7bd085c4aa3d94c2f86a43470754816' | ||
module.exports.LOCAL = 'i-should-pass' | ||
module.exports.DEP_REPO_PERM = 'ADMIN' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "do-you-pass", | ||
"version": "1.0.0", | ||
"description": "Does i-should-pass pass?", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node test.js" | ||
}, | ||
"author": "Andrew Hughes", | ||
"license": "Apache-2.0", | ||
"homepage": "https://github.com/andrewhughes101/do-you-pass", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/andrewhughes101/do-you-pass.git" | ||
}, | ||
"dependencies": { | ||
"i-should-pass": "^1.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
require('dotenv').config() | ||
const tap = require('tap') | ||
const github = require('../lib/github') | ||
const CONFIG = require('./fixtures/config') | ||
|
||
tap.test('package.json can be fetched with a valid url', async tap => { | ||
tap.equal(JSON.stringify(await github.getPackageJson(CONFIG.DEP_ORG, CONFIG.DEP_REPO)), JSON.stringify(CONFIG.PKGJSON)) | ||
// tap.throws( await pkgTest.getPackageJson('not-an-org', 'not-a-repo')) | ||
}) | ||
|
||
tap.test('correct permissions returned for GitHub repo', async tap => { | ||
tap.equal((await github.getPermissions(CONFIG.DEP_ORG, CONFIG.DEP_REPO)), CONFIG.DEP_REPO_PERM) | ||
}) |
Oops, something went wrong.