From 38d61e3463f681320818eea86014c9680a209acf Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 24 Feb 2020 15:38:56 +0800 Subject: [PATCH 1/2] accept URL as well as domain name for --mirror argument do not assume that the mirror mirrors the full directory structure of nodejs.org, actually, some mirros just have the part of `https://nodejs.org/download/release/` mirrored. for instance, https://npm.taobao.org/mirrors/node, and do not assume that the mirror always put the nodejs mirror in its `download/` directory. in this change, a URL is accepted as well as a domain name. if a mirror does not have "://" in it is specified, the default "https:///download/releases" URL is used. this change addresses the comment of https://github.com/ekalinin/nodeenv/pull/208#issuecomment-380434680 also, ignore E127 for multi-line `with` statement, see discussion at https://github.com/PyCQA/pycodestyle/issues/316, which is related to E126, but it also applies this case. Signed-off-by: Kefu Chai --- README.rst | 4 ++++ nodeenv.py | 20 ++++++++++++++------ tests/nodeenv_test.py | 28 ++++++++++++++++++++++++++++ tox.ini | 2 +- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 7743d6d..b9847ac 100644 --- a/README.rst +++ b/README.rst @@ -136,6 +136,10 @@ Install node.js from the source:: $ nodeenv --node=0.10.25 --source env-0.10.25 +Install node.js from a mirror:: + + $ nodeenv --node=10.19.0 --mirror=https://npm.taobao.org/mirrors/node + It's much faster to install from the prebuilt package than Install & compile node.js from source:: diff --git a/nodeenv.py b/nodeenv.py index ebf93b8..dce60e6 100755 --- a/nodeenv.py +++ b/nodeenv.py @@ -47,7 +47,7 @@ join = os.path.join abspath = os.path.abspath iojs_taken = False -src_domain = "nodejs.org" +src_base_url = None is_PY3 = sys.version_info[0] >= 3 is_WIN = platform.system() == 'Windows' @@ -497,9 +497,9 @@ def callit(cmd, show_stdout=True, in_shell=False, def get_root_url(version): if parse_version(version) > parse_version("0.5.0"): - return 'https://%s/download/release/v%s/' % (src_domain, version) + return '%s/v%s/' % (src_base_url, version) else: - return 'https://%s/download/release/' % src_domain + return src_base_url def is_x86_64_musl(): @@ -957,7 +957,7 @@ def create_environment(env_dir, opt): def _get_versions_json(): - response = urlopen('https://%s/download/release/index.json' % src_domain) + response = urlopen('%s/index.json' % src_base_url) return json.loads(response.read().decode('UTF-8')) @@ -1021,17 +1021,25 @@ def main(): exit(1) global iojs_taken - global src_domain + global src_base_url + src_domain = None if opt.io: iojs_taken = True src_domain = "iojs.org" if opt.mirror: - src_domain = opt.mirror + if '://' in opt.mirror: + src_base_url = opt.mirror + else: + src_domain = opt.mirror # use unofficial builds only if musl and no explicitly chosen mirror elif is_x86_64_musl(): src_domain = 'unofficial-builds.nodejs.org' + else: + src_domain = 'nodejs.org' + if src_base_url is None: + src_base_url = 'https://%s/download/release' % src_domain if not opt.node or opt.node.lower() == "latest": opt.node = get_last_stable_node_version() diff --git a/tests/nodeenv_test.py b/tests/nodeenv_test.py index 1296b73..ac0a613 100644 --- a/tests/nodeenv_test.py +++ b/tests/nodeenv_test.py @@ -3,6 +3,7 @@ import os.path import subprocess +import sys import mock import pytest @@ -79,3 +80,30 @@ def test_predeactivate_hook(tmpdir): nodeenv.set_predeactivate_hook(tmpdir.strpath) p = tmpdir.join('bin').join('predeactivate') assert 'deactivate_node' in p.read() + + +def test_mirror_option(): + urls = [('https://npm.taobao.org/mirrors/node', + 'https://npm.taobao.org/mirrors/node/index.json'), + ('npm.some-mirror.com', + 'https://npm.some-mirror.com/download/release/index.json'), + ('', + 'https://nodejs.org/download/release/index.json')] + with open(os.path.join(HERE, 'nodejs_index.json'), 'rb') as f: + def rewind(_): + f.seek(0) + return f + argv = [__file__, '--list'] + for mirror, url in urls: + if mirror: + test_argv = argv + ['--mirror=' + mirror] + else: + test_argv = argv + with mock.patch.object(sys, 'argv', test_argv), \ + mock.patch.object(nodeenv.logger, 'info') as mock_logger, \ + mock.patch.object(nodeenv, 'urlopen', + side_effect=rewind) as mock_urlopen: + nodeenv.src_base_url = None + nodeenv.main() + mock_urlopen.assert_called_with(url) + mock_logger.assert_called() diff --git a/tox.ini b/tox.ini index 5263a28..c713fbc 100644 --- a/tox.ini +++ b/tox.ini @@ -13,7 +13,7 @@ commands = # Needed because we subprocess to ourselves coverage combine coverage report --show-missing --fail-under 55 # TODO: 100 - flake8 nodeenv.py tests setup.py + flake8 --extend-ignore=E127 nodeenv.py tests setup.py [testenv:venv] envdir = venv-nodeenv From 7d3bf01c940b1caff560692b486469cfd5321a21 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 24 Feb 2020 16:10:16 +0800 Subject: [PATCH 2/2] drop iojs support node.js and io.js already merged back together since v4.0. and iojs.org redirects to nodejs.org. so, it does not make sense to offer this option for new developers using node.js >= 4.0 Signed-off-by: Kefu Chai --- Makefile | 10 ---------- README.rst | 12 ------------ nodeenv.py | 37 ++++++++++--------------------------- 3 files changed, 10 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index 24c1b8b..5ff5137 100644 --- a/Makefile +++ b/Makefile @@ -87,16 +87,6 @@ test5: clean python setup.py install && \ nodeenv -p --prebuilt -test6: clean - @echo " =" - @echo " = test6: separate iojs's env" - @echo " =" - @rm -rf env && \ - virtualenv --no-site-packages env && \ - . env/bin/activate && \ - python setup.py install && \ - nodeenv -p --prebuilt --iojs - test7: clean @echo " =" @echo " = test7: freeze for global installation" diff --git a/README.rst b/README.rst index b9847ac..c21bc09 100644 --- a/README.rst +++ b/README.rst @@ -230,18 +230,6 @@ use `shim` script:: $ ./env-4.3/bin/shim --version v0.4.3 - -If you want to install iojs instead of nodejs then use ``--iojs``:: - - $ virtualenv env - $ . env/bin/activate - (env) $ nodeenv --iojs --list - 1.0.0 1.0.1 - (env) $ nodeenv --iojs -p --prebuilt - * Install iojs (1.0.1) ... done. - * Appending data to ~/tmp/env/bin/activate - - Configuration ------------- You can use the INI-style file ``~/.nodeenvrc`` to set default values for many options, diff --git a/nodeenv.py b/nodeenv.py index dce60e6..e7c646d 100755 --- a/nodeenv.py +++ b/nodeenv.py @@ -46,7 +46,6 @@ join = os.path.join abspath = os.path.abspath -iojs_taken = False src_base_url = None is_PY3 = sys.version_info[0] >= 3 @@ -222,15 +221,10 @@ def parse_args(check=True): 'The default is last stable version (`latest`). ' 'Use `system` to use system-wide node.') - parser.add_option( - '-i', '--iojs', - action='store_true', dest='io', default=False, - help='Use iojs instead of nodejs.') - parser.add_option( '--mirror', action="store", dest='mirror', - help='Set mirror server of nodejs.org or iojs.org to download from.') + help='Set mirror server of nodejs.org to download from.') if not is_WIN: parser.add_option( @@ -527,12 +521,12 @@ def get_node_bin_url(version): postfix = '-linux-x64-musl.tar.gz' else: postfix = '-%(system)s-%(arch)s.tar.gz' % sysinfo - filename = '%s-v%s%s' % (get_binary_prefix(), version, postfix) + filename = 'node-v%s%s' % (version, postfix) return get_root_url(version) + filename def get_node_src_url(version): - tar_name = '%s-v%s.tar.gz' % (get_binary_prefix(), version) + tar_name = 'node-v%s.tar.gz' % version return get_root_url(version) + tar_name @@ -546,7 +540,7 @@ def tarfile_open(*args, **kwargs): tf.close() -def download_node_src(node_url, src_dir, opt, prefix): +def download_node_src(node_url, src_dir, opt): """ Download source code """ @@ -565,8 +559,8 @@ def download_node_src(node_url, src_dir, opt, prefix): with ctx as archive: node_ver = re.escape(opt.node) - rexp_string = r"%s-v%s[^/]*/(README\.md|CHANGELOG\.md|LICENSE)"\ - % (prefix, node_ver) + rexp_string = r"node-v%s[^/]*/(README\.md|CHANGELOG\.md|LICENSE)"\ + % node_ver extract_list = [ member for member in members(archive) @@ -608,7 +602,6 @@ def copy_node_from_prebuilt(env_dir, src_dir, node_version): Copy prebuilt binaries into environment """ logger.info('.', extra=dict(continued=True)) - prefix = get_binary_prefix() if is_WIN: dest = join(env_dir, 'Scripts') mkdir(dest) @@ -620,7 +613,7 @@ def copy_node_from_prebuilt(env_dir, src_dir, node_version): else: dest = env_dir - src_folder_tpl = src_dir + to_utf8('/%s-v%s*' % (prefix, node_version)) + src_folder_tpl = src_dir + to_utf8('/node-v%s*' % node_version) src_folder, = glob.glob(src_folder_tpl) copytree(src_folder, dest, True) @@ -689,10 +682,6 @@ def build_node_from_src(env_dir, src_dir, node_src_dir, opt): callit([make_cmd + ' install'], opt.verbose, True, node_src_dir, env) -def get_binary_prefix(): - return to_utf8('node' if not iojs_taken else 'iojs') - - def install_node(env_dir, src_dir, opt): """ Download source code for node.js, unpack it @@ -708,11 +697,10 @@ def install_node(env_dir, src_dir, opt): def install_node_wrapped(env_dir, src_dir, opt): env_dir = abspath(env_dir) - prefix = get_binary_prefix() - node_src_dir = join(src_dir, to_utf8('%s-v%s' % (prefix, opt.node))) + node_src_dir = join(src_dir, to_utf8('node-v%s' % opt.node)) src_type = "prebuilt" if opt.prebuilt else "source" - logger.info(' * Install %s %s (%s) ' % (src_type, prefix, opt.node), + logger.info(' * Install %s node (%s) ' % (src_type, opt.node), extra=dict(continued=True)) if opt.prebuilt: @@ -722,7 +710,7 @@ def install_node_wrapped(env_dir, src_dir, opt): # get src if not downloaded yet if not os.path.exists(node_src_dir): - download_node_src(node_url, src_dir, opt, prefix) + download_node_src(node_url, src_dir, opt) logger.info('.', extra=dict(continued=True)) @@ -1020,14 +1008,9 @@ def main(): logger.error('Installing system node.js on win32 is not supported!') exit(1) - global iojs_taken global src_base_url src_domain = None - if opt.io: - iojs_taken = True - src_domain = "iojs.org" - if opt.mirror: if '://' in opt.mirror: src_base_url = opt.mirror