feat(@embark/utils): "inside monorepo" APIs

This commit is contained in:
Michael Bradley, Jr 2019-09-16 15:39:22 -05:00 committed by Michael Bradley
parent 1ba9e4b0a2
commit de0e12d039
6 changed files with 221 additions and 1 deletions

View File

@ -0,0 +1 @@
// does nothing on purpose, do not delete this .js file

View File

@ -0,0 +1,11 @@
{
"name": "embark-inside-monorepo",
"private": true,
"version": "4.1.1",
"author": "Michael Bradley <michaelsbradleyjr@gmail.com> (https://github.com/michaelsbradleyjr/)",
"description": "If a package from the monorepo can resolve this package then the first package is inside the monorepo",
"keywords": [],
"license": "MIT",
"main": "index.js",
"scripts": {}
}

View File

@ -18,8 +18,14 @@ declare module "embark-utils" {
function escapeHtml(message: any): string;
function embarkPath(...names: string[]): string;
function exit(code?: any): void;
function findMonorepoPackageFromRoot(pkgName: string, prefilter?: null | ((pkgName: string) => (pkgJsonPath: string) => boolean)): Promise<string>;
function findMonorepoPackageFromRootSync(pkgName: string, prefilter?: null | ((pkgName: string) => (pkgJsonPath: string) => boolean)): string;
function findNextPort(port: number): Promise<number>;
function isEs6Module(module: any): boolean;
function isInsideMonorepo(): Promise<boolean>;
function isInsideMonorepoSync(): boolean;
function monorepoRootPath(): Promise<string>;
function monorepoRootPathSync(): string;
function jsonFunctionReplacer(key: any, value: any): any;
function fuzzySearch(text: string, list: any, filter: any): any;
function getExternalContractUrl(file: string, provideUrl: string): string;

View File

@ -45,7 +45,7 @@
"extends": "../../../.eslintrc.json"
},
"dependencies": {
"@babel/runtime-corejs2": "7.3.1",
"@babel/runtime-corejs2": "7.6.0",
"bip39": "3.0.2",
"clipboardy": "1.2.3",
"colors": "1.3.2",
@ -55,6 +55,7 @@
"follow-redirects": "1.8.0",
"fs-extra": "7.0.1",
"fuzzy": "0.1.3",
"glob": "7.1.4",
"globule": "1.2.1",
"merge": "1.2.1",
"multihashes": "0.4.14",
@ -73,6 +74,7 @@
"@types/node": "10.11.7",
"@types/pretty-ms": "5.0.1",
"cross-env": "5.2.0",
"embark-inside-monorepo": "^4.1.1",
"eslint": "5.7.0",
"npm-run-all": "4.1.5",
"rimraf": "3.0.0",

View File

@ -50,6 +50,15 @@ import { compact, last, recursiveMerge, groupBy } from './collections';
import { prepareForCompilation } from './solidity/remapImports';
import { File, getExternalContractUrl, Types } from './file';
import {
findMonorepoPackageFromRoot,
findMonorepoPackageFromRootSync,
isInsideMonorepo,
isInsideMonorepoSync,
monorepoRootPath,
monorepoRootPathSync
} from './monorepo';
function timer(ms) {
const then = Date.now();
return new Promise(resolve => (
@ -312,6 +321,8 @@ const Utils = {
soliditySha3,
recursiveMerge,
prepareContractsConfig,
findMonorepoPackageFromRoot,
findMonorepoPackageFromRootSync,
getWeiBalanceFromString,
getHexBalanceFromString,
getExternalContractUrl,
@ -321,6 +332,10 @@ const Utils = {
httpsGet,
httpGetJson,
httpsGetJson,
isInsideMonorepo,
isInsideMonorepoSync,
monorepoRootPath,
monorepoRootPathSync,
pingEndpoint,
setUpEnv,
sha512,

View File

@ -0,0 +1,185 @@
/* global __dirname module require */
const findUp = require('find-up');
const {readJson, readJsonSync} = require('fs-extra');
const {promisify} = require('util');
const glob = require('glob');
const globP = promisify(glob);
const {basename, dirname, join} = require('path');
let _isInsideMonorepo = null;
let _monorepoRootPath = null;
const embarkInsidePkg = 'embark-inside-monorepo';
const lernaJson = 'lerna.json';
const couldNotFindRootErrorMsg = `could not find embark's monorepo's root starting from ${__dirname}`;
const notInsideErrorMsg = function (dir) {
return `package ${dir} is not inside embark's monorepo`;
};
async function isInsideMonorepo() {
if (_isInsideMonorepo === null) {
try {
_isInsideMonorepo = !!(
await findUp(`node_modules/${embarkInsidePkg}`, {cwd: __dirname})
);
} catch (err) {
_isInsideMonorepo = false;
}
}
return _isInsideMonorepo;
}
function isInsideMonorepoSync() {
if (_isInsideMonorepo === null) {
try {
_isInsideMonorepo = !!require.resolve(
embarkInsidePkg, {paths: [__dirname]}
);
} catch (err) {
_isInsideMonorepo = false;
}
}
return _isInsideMonorepo;
}
async function monorepoRootPath() {
if (!(await isInsideMonorepo())) {
throw new Error(
notInsideErrorMsg(dirname(await findUp('package.json', {cwd: __dirname})))
);
}
if (_monorepoRootPath === null) {
try {
_monorepoRootPath = dirname(await findUp(lernaJson, {cwd: __dirname}));
} catch (err) {
_monorepoRootPath = false;
throw new Error(couldNotFindRootErrorMsg);
}
}
if (_monorepoRootPath) {
return _monorepoRootPath;
}
throw new Error(couldNotFindRootErrorMsg);
}
function monorepoRootPathSync() {
if (!isInsideMonorepoSync()) {
throw new Error(
notInsideErrorMsg(dirname(findUp.sync('package.json', {cwd: __dirname})))
);
}
if (_monorepoRootPath === null) {
try {
_monorepoRootPath = dirname(findUp.sync(lernaJson, {cwd: __dirname}));
} catch (err) {
_monorepoRootPath = false;
throw new Error(couldNotFindRootErrorMsg);
}
}
if (_monorepoRootPath) {
return _monorepoRootPath;
}
throw new Error(couldNotFindRootErrorMsg);
}
const globArgs = function(monorepoRootPath) {
return [
'**/package.json',
{
cwd: monorepoRootPath,
ignore: [
'**/node_modules/**',
'package.json',
'scripts/**',
'site/**'
]
}
];
};
const couldNotFindPkgErrorMsg = function(pkgName, monorepoRootPath) {
return `could not find any package named ${pkgName} inside the embark monorepo at ${monorepoRootPath}, if it is known to exist try disabling the prefilter by passing null as the second argument`;
};
const partialMatch = function(pkgName) {
if (pkgName.startsWith('embark-')) {
pkgName = pkgName.slice(7);
}
return function (pkgJsonPath) {
let dir = basename(dirname(pkgJsonPath));
return dir.includes(pkgName);
};
};
async function findMonorepoPackageFromRoot(pkgName, prefilter = partialMatch) {
const rootPath = await monorepoRootPath();
const pkgJsonPaths = (await globP(...globArgs(rootPath)));
prefilter = prefilter ? prefilter(pkgName) : () => true;
const jsons = function *() {
for (let path of pkgJsonPaths) {
if (!prefilter(path)) continue;
path = join(rootPath, path);
yield Promise.all([readJson(path), path]);
}
};
let pkgPath;
for await (const [json, path] of jsons()) {
if (json.name === pkgName) {
pkgPath = dirname(path);
break;
}
}
if (pkgPath) return pkgPath;
throw new Error(couldNotFindPkgErrorMsg(pkgName, rootPath));
}
function findMonorepoPackageFromRootSync(pkgName, prefilter = partialMatch) {
const rootPath = monorepoRootPathSync();
const pkgJsonPaths = glob.sync(...globArgs(rootPath));
prefilter = prefilter ? prefilter(pkgName) : () => true;
const jsons = function *() {
for (let path of pkgJsonPaths) {
if (!prefilter(path)) continue;
path = join(rootPath, path);
yield [readJsonSync(path), path];
}
};
let pkgPath;
for (const [json, path] of jsons()) {
if (json.name === pkgName) {
pkgPath = dirname(path);
break;
}
}
if (pkgPath) return pkgPath;
throw new Error(couldNotFindPkgErrorMsg(pkgName, rootPath));
}
module.exports = {
findMonorepoPackageFromRoot,
findMonorepoPackageFromRootSync,
isInsideMonorepo,
isInsideMonorepoSync,
monorepoRootPath,
monorepoRootPathSync
};