New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@pipcook/boa

Package Overview
Dependencies
Maintainers
5
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pipcook/boa - npm Package Compare versions

Comparing version 1.2.1-c9eced5-beta.0 to 1.2.1-fc7360e-beta.0

index.d.ts

2

lib/delegators/builtins.enumerate.js

@@ -1,3 +0,1 @@

class Enumerate {

@@ -4,0 +2,0 @@ constructor(T, wrap) {

@@ -1,3 +0,1 @@

module.exports = () => {

@@ -4,0 +2,0 @@ return function PythonCallable() {

@@ -1,37 +0,24 @@

const fs = require('fs');
'use strict';
const vm = require('vm');
const util = require('util');
const path = require('path');
const native = require('bindings')('boa');
const debug = require('debug')('boa');
const utils = require('./utils');
const DelegatorLoader = require('./delegator-loader');
// internal symbols
const IterIdxForSeqSymbol = Symbol('The iteration index for sequence');
const PyGetAttrSymbol = Symbol('PYTHON_GETATTR_SYMBOL');
const PySetAttrSymbol = Symbol('PYTHON_SETATTR_SYMBOL');
const PyGetItemSymbol = Symbol('PYTHON_GETITEM_SYMBOL');
const PySetItemSymbol = Symbol('PYTHON_SETITEM_SYMBOL');
const {
notEmpty,
getIndent,
removeIndent,
asHandleObject,
GetOwnershipSymbol,
PyGetAttrSymbol,
PySetAttrSymbol,
PyGetItemSymbol,
PySetItemSymbol,
} = require('./utils');
const { SharedPythonObject } = require('./worker');
const { condaPath, pyInst, globals, builtins } = require('./factory');
const { wrap, _internalWrap } = require('./proxy');
// read the conda path from the .CONDA_INSTALL_DIR
// eslint-disable-next-line no-sync
const condaPath = fs.readFileSync(path.join(__dirname, '../.CONDA_INSTALL_DIR'), 'utf8');
if (!process.env.PYTHONHOME) {
process.env.PYTHONHOME = condaPath;
}
// create the global-scoped instance
let pyInst = global.__pipcook_boa_pyinst__;
if (pyInst == null) {
pyInst = new native.Python(process.argv.slice(1));
global.__pipcook_boa_pyinst__ = pyInst;
}
const importedNames = [];
// FIXME(Yorkie): move to costa or daemon?
const sharedModules = ['sys', 'torch'];
const globals = pyInst.globals();
const builtins = pyInst.builtins();
const delegators = DelegatorLoader.load();
let defaultSysPath = [];

@@ -42,14 +29,2 @@

function getTypeInfo(T) {
const typeo = builtins.__getitem__('type').invoke(asHandleObject(T));
const tinfo = { module: null, name: null };
if (typeo.__hasattr__('__module__')) {
tinfo.module = typeo.__getattr__('__module__').toString();
}
if (typeo.__hasattr__('__name__')) {
tinfo.name = typeo.__getattr__('__name__').toString();
}
return tinfo;
}
function setenv(externalSearchPath) {

@@ -85,74 +60,2 @@ const sys = pyInst.import('sys');

function dump(T) {
return pyInst.import('json')
.__getattr__('dumps')
.invoke(asHandleObject(T), {
// use str method to serialize those fields which cannot be serialized by default
default: _internalWrap(builtins).str,
[native.NODE_PYTHON_KWARGS_NAME]: true,
});
}
function getDelegator(type) {
if (typeof type === 'string') {
return delegators[type];
}
const { module, name } = type;
if (Object.prototype.hasOwnProperty.call(delegators, module)) {
return delegators[module][name];
}
return undefined;
}
// The function `wrap(T)` is used to return an object or value for using.
// It depends on the type of `T` in Python world, usually it returns a
// `Proxy` object that's based on `T`, when the type could be represented
// as number/boolean/string/null, the return value would be converted to
// corresponding JS primative.
function wrap(T) {
// if `T` is null or undefined, returning itself by default.
if (T === null || T == undefined) {
return T;
}
const type = getTypeInfo(T);
debug(`start wrapping an object, and its type is "${type.module}.${type.name}"`);
// if `type` is "NoneType", returning the null.
if (type.module === 'builtins' && type.name === 'NoneType') {
return null;
}
// FIXME(Yorkie): directly returning the primitive value on the
// following conditions.
if ([
/** python types convert to primitive values. */
'int', /** Number */
'int64', /** BigInt */
'float', /** Number */
'float64', /** BigDecimal(depends on new tc39 proposal) */
'bool', /** Boolean */
'str', /** String */
/** except for null and undefined */
].includes(type.name)) {
return T.toPrimitive();
}
let fn = getDelegator(T.isCallable() ? 'callee' : type);
if (typeof fn !== 'function') {
fn = getDelegator('default');
}
// use internalWrap to generate proxy object with corresponding delegator.
const wrapped = _internalWrap(T, fn(T, wrap));
T[native.NODE_PYTHON_WRAPPED_NAME] = wrapped;
return wrapped;
}
function asHandleObject(T) {
return {
// namely shortcut for Python object.
[native.NODE_PYTHON_HANDLE_NAME]: T
};
}
function asBytesObject(str) {

@@ -165,305 +68,2 @@ return {

function _internalWrap(T, src={}) {
Object.defineProperties(src, {
/**
* @property native.NODE_PYTHON_WRAPPED_NAME
* @private
*/
[native.NODE_PYTHON_HANDLE_NAME]: {
enumerable: true,
writable: false,
value: T,
},
/**
* @method native.NODE_PYTHON_JS_DISPATCH
* @private
*/
[native.NODE_PYTHON_JS_DISPATCH]: {
enumerable: true,
// FIXME(Yorkie): temporarily set `configurable` to false here.
// See https://github.com/v8/v8/blob/7.9.317/src/objects/objects.cc#L1176-L1179
//
// The proxy object's get trap handler is inconsistent with this descriptor when
// the value is a function, which means the `inconsistent` to be true, then throwing
// a `kProxyGetNonConfigurableData` error.
//
// In order to better solve, we need to define both `get` and `has` traps in the
// proxy object, and move descriptors to the trap handler.
configurable: true,
writable: false,
value: function(fn, isClassMethod, ...args) {
if (isClassMethod) {
return fn.apply(wrap(args[0]), args.slice(1).map(wrap));
} else {
return fn.apply(this, args.map(wrap));
}
},
},
/**
* @method invoke
* @param {object} args
* @private
*/
invoke: {
enumerable: false,
writable: false,
value: args => {
return T.invoke.apply(T, args);
},
},
/**
* @method toString
* @public
*/
toString: {
configurable: true,
enumerable: false,
writable: false,
value: () => T.toString(),
},
/**
* @method toJSON
* @public
*/
toJSON: {
configurable: true,
enumerable: false,
writable: false,
value: () => {
const type = getTypeInfo(T);
let str;
if (type.module === 'numpy') {
str = dump(T.__getattr__('tolist').invoke());
} else {
str = dump(T);
}
// TODO(Yorkie): more performant way to serialize objects?
return JSON.parse(wrap(str));
},
},
/**
* Shortcut for slicing object.
* @method slice
* @public
*/
slice: {
configurable: true,
enumerable: false,
writable: false,
value: (start, end, step) => {
// slice(start, end, step)
const slice = builtins.__getitem__('slice')
.invoke(start, end, step);
// use the slice object as the key for s[x:y:z]
return wrap(T.__getitem__(asHandleObject(slice)));
},
},
/**
* This is used to cusom the console.log output by calling toString().
* @method util.inspect.custom
* @public
*/
[util.inspect.custom]: {
configurable: true,
enumerable: false,
writable: false,
value: () => T.toString(),
},
/**
* @method Symbol.toPrimitive
* @param {string} hint
* @public
*/
// Forward compatible with newer `toPrimitive` spec
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive
[Symbol.toPrimitive]: {
configurable: true,
enumerable: false,
writable: false,
value: () => T.toString(),
},
/**
* Implementation of ES iterator protocol, See:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
*
* @method Symbol.iterator
* @public
*/
[Symbol.iterator]: {
configurable: true,
enumerable: false,
writable: false,
value: () => {
if (T.isIterator()) {
return {
next: () => {
const curr = T.next();
return {
done: curr.done,
value: wrap(curr.value),
};
},
};
}
if (T.isSequence()) {
return {
next: function next() {
if (typeof this[IterIdxForSeqSymbol] === 'number') {
this[IterIdxForSeqSymbol] += 1;
} else {
this[IterIdxForSeqSymbol] = 0;
}
const lengthOfSeq = builtins.__getitem__('len')
.invoke(asHandleObject(T)).toPrimitive();
const index = this[IterIdxForSeqSymbol];
if (index >= lengthOfSeq) {
return { done: true, value: undefined };
}
return {
done: false,
value: wrap(T.__getitem__(index)),
};
}
};
}
throw new TypeError('object is not iteratable or sequence.');
},
},
/**
* @method __hash__
* @public
*/
__hash__: {
configurable: true,
enumerable: true,
writable: false,
value: () => T.__hash__(),
},
/**
* @method [PyGetAttrSymbol]
* @public
*/
[PyGetAttrSymbol]: {
configurable: true,
enumerable: true,
writable: false,
value: k => wrap(T.__getattr__(k)),
},
/**
* @method [PySetAttrSymbol]
* @public
*/
[PySetAttrSymbol]: {
configurable: true,
enumerable: true,
writable: false,
value: (k, v) => T.__setattr__(k, v),
},
/**
* @method [PyGetItemSymbol]
* @public
*/
[PyGetItemSymbol]: {
configurable: true,
enumerable: true,
writable: false,
value: k => wrap(T.__getitem__(k)),
},
/**
* @method [PySetItemSymbol]
* @public
*/
[PySetItemSymbol]: {
configurable: true,
enumerable: true,
writable: false,
value: (k, v) => T.__setitem__(k, v),
},
});
// Create the proxy object for handlers
let newTarget;
return (newTarget = new Proxy(src, {
'get'(target, name) {
debug(`get property on "${target.constructor.name}", ` +
`name is "${name.toString()}"`);
const { hasOwnProperty } = Object.prototype;
const constructProto = target.constructor.prototype;
if (hasOwnProperty.call(target, name) /* check for own property */ ||
hasOwnProperty.call(constructProto, name) /* check for inherited one-level */
) {
const value = target[name];
debug(`found "${name.toString()}" from object own properties ` +
`or one-level properties.`);
if (typeof value === 'function') {
// FIXME(Yorkie): make sure the function's this is correct.
return value.bind(newTarget);
} else {
return value;
}
}
/** Enter the Python world. */
if (typeof name === 'string') {
if (/^[0-9]+$/.test(name)) {
debug('name is detected to be an index.');
const n = parseInt(name, 10);
return wrap(T.__getitem__(n));
}
if (T.__hasattr__(name)) {
debug(`found "${name}" as python attr`);
return wrap(T.__getattr__(name));
}
}
try {
const r = T.__getitem__(name);
if (r != null) {
debug(`found "${name.toString()}" as python item`);
return wrap(r);
}
} catch (e) {
debug(`accessing the item["${name.toString()}"] failed ` +
`with ${e.message}`);
}
},
'set'(target, name, value) {
if (typeof name === 'string') {
if (/^[0-9]+$/.test(name)) {
return T.__setitem__(parseInt(name, 10), value) !== -1;
}
if (T.__hasattr__(name)) {
return T.__setattr__(name, value) !== -1;
}
}
let r = T.__setitem__(name, value);
if (r === -1) {
r = T.__setattr__(name, value);
}
return r !== -1;
},
'apply'(target, thisArg, argumentsList) {
return wrap(target.invoke(argumentsList));
},
'construct'(target, argumentsList, newClass) {
if (newClass.name === 'PythonCallable') {
return wrap(target.invoke(argumentsList));
}
if (!newClass.prototype.$pyclass) {
const pyclass = T.createClass(newClass.name, target);
Object.getOwnPropertyNames(newClass.prototype)
.filter(name => name !== 'constructor' || name !== '__init__')
.forEach(name => {
pyclass.setClassMethod(name, newClass.prototype[name]);
});
newClass.prototype.$pyclass = wrap(pyclass);
}
// return the instance
return newClass.prototype.$pyclass.apply(null, argumentsList);
},
}));
}
module.exports = {

@@ -477,22 +77,5 @@ /**

/**
* Public symbols
* @class SharedPythonObject
*/
symbols: {
/**
* __getattr__
*/
PyGetAttrSymbol,
/**
* __setattr__
*/
PySetAttrSymbol,
/**
* __getitem__
*/
PyGetItemSymbol,
/**
* __setitem__
*/
PySetItemSymbol,
},
SharedPythonObject,
/*

@@ -574,2 +157,6 @@ * Import a Python module.

},
/**
* Evaluate a Python expression.
* @param {string} strs the Python exprs.
*/
'eval': (strs, ...params) => {

@@ -599,9 +186,35 @@ let src = '';

// for multiline executing.
const lines = src.split('\n').filter(utils.notEmpty);
const indent = utils.getIndent(lines);
const lines = src.split('\n').filter(notEmpty);
const indent = getIndent(lines);
return wrap(pyInst.eval(
lines.map(utils.removeIndent(indent)).join('\n'),
lines.map(removeIndent(indent)).join('\n'),
{ globals: env, locals: env }
));
},
/**
* Symbols
*/
symbols: {
/**
* The symbol is used to get the ownership value on an object.
*/
GetOwnershipSymbol,
/**
* __getattr__
*/
PyGetAttrSymbol,
/**
* __setattr__
*/
PySetAttrSymbol,
/**
* __getitem__
*/
PyGetItemSymbol,
/**
* __setitem__
*/
PySetItemSymbol,
},
};

@@ -0,3 +1,11 @@

'use strict';
const { NODE_PYTHON_HANDLE_NAME } = require('bindings')('boa');
const GetOwnershipSymbol = Symbol('GET_OWNERSHIP');
const PyGetAttrSymbol = Symbol('PYTHON_GETATTR_SYMBOL');
const PySetAttrSymbol = Symbol('PYTHON_SETATTR_SYMBOL');
const PyGetItemSymbol = Symbol('PYTHON_GETITEM_SYMBOL');
const PySetItemSymbol = Symbol('PYTHON_SETITEM_SYMBOL');
function notEmpty(line) {

@@ -23,4 +31,20 @@ return /^\s*$/.test(line) === false;

exports.notEmpty = notEmpty;
exports.getIndent = getIndent;
exports.removeIndent = removeIndent;
function asHandleObject(T) {
return {
// namely shortcut for Python object.
[NODE_PYTHON_HANDLE_NAME]: T
};
}
module.exports = {
notEmpty,
getIndent,
removeIndent,
asHandleObject,
// symbols
GetOwnershipSymbol,
PyGetAttrSymbol,
PySetAttrSymbol,
PyGetItemSymbol,
PySetItemSymbol,
};
{
"name": "@pipcook/boa",
"version": "1.2.1-c9eced5-beta.0",
"version": "1.2.1-fc7360e-beta.0",
"description": "Use Python modules seamlessly in Node.js",

@@ -8,8 +8,17 @@ "main": "lib/index.js",

"clean": "sh tools/clean-python.sh && make -C ./pybind11/ clean",
"preinstall": "node tools/check-dependence.js && make -C ./pybind11/ && node tools/install-python.js && node tools/install-requirements.js",
"predeps": "tools/check-dependence.js",
"deps": "make -C ./pybind11/ && tools/install-python.js",
"preinstall": "npm run deps",
"postinstall": "npm run build",
"test": "tape ./tests/**/*.js",
"lint": "eslint . -c .eslintrc.js --no-eslintrc && ./clang-format.py",
"pretest": "npm run lint",
"pretest:js": "bip install numpy",
"test": "npm run test:js && npm run test:ts",
"test:js": "tape ./tests/**/*.js",
"test:ts": "ts-node ./node_modules/.bin/tape ./tests/**/*.ts",
"cov": "nyc --reporter=text-summary npm run test",
"cov:report": "nyc report -r=lcov",
"lint": "npm run lint:js && npm run lint:clang",
"lint:js": "eslint . -c .eslintrc.js --no-eslintrc",
"lint:clang": "./clang-format.py",
"build": "npm run compile",
"pretest": "npm run lint",
"codecov": "nyc report --reporter=lcovonly && codecov",

@@ -43,6 +52,8 @@ "htmlcov": "nyc report --reporter=html",

"devDependencies": {
"@types/tape": "^4.13.0",
"codecov": "^3.6.5",
"eslint": "^6.7.2",
"nyc": "^14.1.1",
"tape": "^5.0.1"
"nyc": "^15.1.0",
"tape": "^5.0.1",
"ts-node": "^8.6.2"
},

@@ -52,3 +63,3 @@ "publishConfig": {

},
"gitHead": "df6a138b57f1958f80504af07c1990c51784d2a3"
"gitHead": "1d38a9b2cc96eb9df2e11696110677bd37211b28"
}

@@ -0,1 +1,3 @@

#!/usr/bin/env node
'use strict';

@@ -16,3 +18,3 @@ const { run, PLATFORM } = require('./utils');

} else {
throw new TypeError(`No support for your platform ${PLATFORM}`);
throw new TypeError(`no support for your platform ${PLATFORM}`);
}

@@ -19,0 +21,0 @@

@@ -0,1 +1,3 @@

#!/usr/bin/env node
'use strict';

@@ -2,0 +4,0 @@

@@ -0,45 +1,47 @@

#!/usr/bin/env node
'use strict';
const { run, py, initAndGetCondaPath, PLATFORM, ARCH } = require('./utils');
const utils = require('./utils');
const fs = require('fs');
const path = require('path');
let CONDA_DOWNLOAD_PREFIX = 'https://repo.anaconda.com/miniconda';
if (process.env.BOA_TUNA) {
CONDA_DOWNLOAD_PREFIX = 'https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda';
const run = utils.run.bind(utils);
const py = utils.py.bind(utils);
if (!utils.shouldInstallConda()) {
console.info('skip installing the python from conda.');
return process.exit(0);
}
if (process.env.BOA_CONDA_MIRROR) {
CONDA_DOWNLOAD_PREFIX = process.env.BOA_CONDA_MIRROR;
}
const CONDA_LOCAL_PATH = initAndGetCondaPath();
let condaDownloadName = 'Miniconda3-4.7.12.1';
// download and install conda
const remoteURL = utils.getCondaRemote();
const installDir = utils.resolveAndUpdateCondaPath();
const downloader = utils.getCondaDownloaderName();
if (PLATFORM === 'linux') {
condaDownloadName += '-Linux';
} else if (PLATFORM === 'darwin') {
condaDownloadName += '-MacOSX';
} else {
throw new TypeError(`No support for your platform ${PLATFORM}`);
// fetch the downloader file if that doesn't exist.
if (!fs.existsSync(downloader)) {
run('curl', `${remoteURL}/${downloader}`, '>', downloader);
}
if (ARCH === 'x64') {
condaDownloadName += '-x86_64';
} else if (PLATFORM !== 'darwin') {
condaDownloadName += '-x86';
// check if the python is installed correctly, we will skip the installation
// when it's installed before.
if (!utils.shouldPythonInstalledOn(installDir)) {
// clean the install dir.
run('rm', '-rf', installDir);
// install
run('sh', downloader, `-f -b -p ${installDir}`);
}
condaDownloadName = `${condaDownloadName}.sh`;
if (!fs.existsSync(condaDownloadName)) {
run(`curl ${CONDA_DOWNLOAD_PREFIX}/${condaDownloadName} > ${condaDownloadName}`);
// cleanup the standard libs.
if (utils.PLATFORM === 'darwin') {
run('rm', '-rf', `${installDir}/lib/libc++*`);
} else if (utils.PLATFORM === 'linux') {
run('rm', '-rf', `${installDir}/lib/libstdc++.so*`);
run('rm', '-rf', `${installDir}/lib/libgcc_s.so*`);
}
if (!fs.existsSync(path.join(CONDA_LOCAL_PATH, 'bin', 'python'))) {
run('rm', `-rf ${CONDA_LOCAL_PATH}`);
run('sh', `./${condaDownloadName}`, `-f -b -p ${CONDA_LOCAL_PATH}`);
run('rm', `-rf ${CONDA_LOCAL_PATH}/lib/libstdc++.so*`);
run('rm', `-rf ${CONDA_LOCAL_PATH}/lib/libgcc_s.so*`);
}
// dump info
py(`${installDir}/bin/conda`, 'info -a');
// dump info
py(`${CONDA_LOCAL_PATH}/bin/conda`, 'info -a');
// install python packages
utils.installPythonPackages();

@@ -7,47 +7,265 @@ 'use strict';

const { execSync } = require('child_process');
const { BOA_CONDA_PREFIX, BOA_TUNA } = process.env;
// Constants
const CONDA_INSTALL_DIR = path.join(__dirname, '../.CONDA_INSTALL_DIR');
let { BOA_CONDA_INDEX } = process.env;
const CONDA_INSTALL_NAME = '.miniconda';
// Environment variables
let {
/**
* The prefix path for choosing the conda directory, possible values are:
* - {\@package} represents a relative path to the boa installed package.
* - {\@cwd} represents a relative path to the current working directory it depends on shell.
* - {string} represents a absolute path to your installed conda path.
*
* Note that, if the variable is specified with relative path, we will throw an error.
*/
BOA_CONDA_PREFIX = '@package',
/**
* The boolean if installing from tuna mirror.
* @boolean
*/
BOA_TUNA,
/**
* The boolean if installing the conda.
*/
BOA_FORCE_INSTALL,
/**
* The conda remote URL, default is https://repo.anaconda.com/miniconda.
* @string
*/
BOA_CONDA_REMOTE = 'https://repo.anaconda.com/miniconda',
BOA_CONDA_MIRROR,
/**
* The conda version to download from remote URL.
* @string
*/
BOA_CONDA_VERSION = 'Miniconda3-4.7.12.1',
/**
* The conda index URI, if `BOA_TUNA` is specified, it will be set.
* @string
*/
BOA_CONDA_INDEX,
/**
* The python library version, for example 3.7m
* @string
*/
BOA_PYTHON_VERSION = '3.7m',
/**
* Install the base packages: numpy/scikit/...
*/
BOA_PACKAGE_BASE,
/**
* Install the cv packages: opencv
*/
BOA_PACKAGE_CV,
} = process.env;
// Check for BOA_CONDA_PREFIX, throw an TypeError when it's not a relative path.
if (!/\@(package|cwd)/.test(BOA_CONDA_PREFIX) && !path.isAbsolute(BOA_CONDA_PREFIX)) {
throw new TypeError('BOA_CONDA_PREFIX is required to be an absolute path');
}
// aliases
if (typeof BOA_CONDA_MIRROR === 'string' && BOA_CONDA_MIRROR.length > 0) {
BOA_CONDA_REMOTE = BOA_CONDA_MIRROR;
}
// Specify BOA_TUNA for simplifying the env setup.
if (BOA_TUNA && !BOA_CONDA_INDEX) {
if (BOA_TUNA) {
BOA_CONDA_REMOTE = 'https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda';
BOA_CONDA_INDEX = 'https://pypi.tuna.tsinghua.edu.cn/simple';
}
exports.run = (...args) => execSync.call(null, args.join(' '), { stdio: 'inherit' });
exports.PLATFORM = os.platform();
exports.ARCH = os.arch();
module.exports = {
/**
* Call to `os.platform()`.
*/
PLATFORM: os.platform(),
/**
* Call to `os.arch()`
*/
ARCH: os.arch(),
exports.getCondaPath = () => fs.readFileSync(CONDA_INSTALL_DIR, 'utf8');
exports.printCondaPath = () => console.log(this.getCondaPath());
exports.initAndGetCondaPath = () => {
let condaPath;
if (BOA_CONDA_PREFIX === '@cwd' || !BOA_CONDA_PREFIX) {
condaPath = path.join(process.cwd(), '.miniconda');
} else if (BOA_CONDA_PREFIX === '@package') {
condaPath = path.join(__dirname, '../.miniconda');
} else {
condaPath = path.join(BOA_CONDA_PREFIX, '.miniconda');
}
fs.writeFileSync(CONDA_INSTALL_DIR, condaPath, 'utf8');
return condaPath;
};
/**
* Compute the state if the build status should install conda.
*/
shouldInstallConda() {
if ('@package' === BOA_CONDA_PREFIX) {
return true;
}
let expectedPath = BOA_CONDA_PREFIX;
if (/^\@cwd/.test(expectedPath)) {
expectedPath = expectedPath.replace('@cwd', process.cwd());
}
if (!fs.existsSync(expectedPath)) {
console.warn(`found the path(${expectedPath}) not exists, conda installation has been switched on.`);
return true;
}
return false;
},
exports.py = (...args) => {
const { run, getCondaPath } = exports;
const CONDA_LOCAL_PATH = getCondaPath();
const Python = path.join(CONDA_LOCAL_PATH, 'bin/python');
const cmds = [Python].concat(args);
return run(...cmds);
};
/**
* Resolves the conda path by configs, then update it to the CONDA_INSTALL_DIR dot file, it returns
* the resolved value.
*/
resolveAndUpdateCondaPath() {
let resolvedPrefix;
if (BOA_CONDA_PREFIX === '@package') {
resolvedPrefix = path.join(__dirname, '..');
} else if (/^\@cwd/.test(BOA_CONDA_PREFIX)) {
resolvedPrefix = (BOA_CONDA_PREFIX + '').replace('@cwd', process.cwd());
} else {
resolvedPrefix = BOA_CONDA_PREFIX;
}
const str = path.join(resolvedPrefix, CONDA_INSTALL_NAME);
fs.writeFileSync(CONDA_INSTALL_DIR, str, 'utf8');
return str;
},
exports.pip = (...args) => {
const { py, getCondaPath } = exports;
const CONDA_LOCAL_PATH = getCondaPath();
const PIP = path.join(CONDA_LOCAL_PATH, 'bin/pip');
const cmds = [PIP].concat(args);
if (BOA_CONDA_INDEX) {
cmds.push(`-i ${BOA_CONDA_INDEX}`);
}
return py(...cmds);
/**
* Return the conda remote URL.
*/
getCondaRemote() {
return BOA_CONDA_REMOTE;
},
/**
* Get the conda directory absolute path.
*/
getCondaPath() {
if (!fs.existsSync(CONDA_INSTALL_DIR)) {
throw new TypeError(`${CONDA_INSTALL_DIR} not found, please reinstall "@pipcook/boa".`);
}
const condaPath = fs.readFileSync(CONDA_INSTALL_DIR, 'utf8');
if (!condaPath || !fs.existsSync(condaPath)) {
this.run('rm', '-rf', CONDA_INSTALL_DIR);
throw new TypeError(`invalid CONDA_INSTALL_DIR file, please reinstall "@pipcook/boa".`);
}
return condaPath;
},
/**
* Return the complete conda URL to be downloaded the specific version.
*/
getCondaDownloaderName() {
let downloaderName = (BOA_CONDA_VERSION + '');
// matches for platforms: linux/macos
if (this.PLATFORM === 'linux') {
downloaderName += '-Linux';
} else if (this.PLATFORM === 'darwin') {
downloaderName += '-MacOSX';
} else {
throw new TypeError(`no support for platform ${PLATFORM}`);
}
// matches for archs: x64/x86/ppc64/?
if (this.ARCH === 'x64') {
downloaderName += '-x86_64';
} else if (this.ARCH === 'ppc64') {
downloaderName += '-ppc64le';
} else {
if (this.PLATFORM !== 'darwin') {
downloaderName += '-x86';
}
}
return `${downloaderName}.sh`;
},
/**
* Get the absolute path of the python library, this is used to compile with.
*/
getPythonLibraryAbsPath() {
return path.join(this.getCondaPath(), 'lib');
},
/**
* Get the runpath/rpath of the python library, this is used to load dynamically.
*/
getPythonLibraryRunPath() {
if (BOA_CONDA_PREFIX === '@packages') {
const prefix = PLATFORM === 'darwin' ? '@loader_path' : '$$ORIGIN';
return `${prefix}/../../${CONDA_INSTALL_NAME}/lib`;
} else {
return this.getPythonLibraryAbsPath();
}
},
/**
* Returns if the python should be installed on the current prefix. To install the Python always,
* set the `BOA_FORCE_INSTALL=1` to return false forcily.
* @param {string} prefix
*/
shouldPythonInstalledOn(prefix) {
if (BOA_FORCE_INSTALL) {
return false;
}
return fs.existsSync(path.join(prefix, 'bin/python'));
},
/**
* Get the Python version to be used by Boa.
*/
getPythonVersion() {
// TODO(Yorkie): fetch the default python version from conda or other sources.
return BOA_PYTHON_VERSION;
},
/**
* Get the path of Python headers.
*/
getPythonHeaderPath() {
return `${this.getCondaPath()}/include/python${this.getPythonVersion()}`;
},
/**
* Install the Python packages by the BOA_PACKAGE_* variables.
*/
installPythonPackages() {
const packagesToInstall = [];
if (BOA_PACKAGE_BASE) {
packagesToInstall.push('numpy');
packagesToInstall.push('scikit-learn');
}
if (BOA_PACKAGE_CV) {
packagesToInstall.push('opencv-python');
}
for (let pkg of packagesToInstall) {
this.pip('install', pkg, '--default-timeout=1000');
}
},
/**
* Execute a shell command.
* @param {...any} args
*/
run(...args) {
const cmd = args.join(' ');
console.info(`sh "${cmd}"`);
return execSync.call(null, cmd, { stdio: 'inherit' });
},
/**
* Execute a python command.
* @param {...any} args
*/
py(...args) {
const python = path.join(this.getCondaPath(), 'bin/python');
const cmds = [ python ].concat(args);
return this.run(...cmds);
},
/**
* Execute a pip command.
* @param {...any} args
*/
pip(...args) {
const pip = path.join(this.getCondaPath(), 'bin/pip');
const cmds = [ pip ].concat(args);
if (BOA_CONDA_INDEX) {
cmds.push(`-i ${BOA_CONDA_INDEX}`);
}
cmds.push('--timeout=5');
return this.py(...cmds);
},
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc