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 7743d6d..c21bc09 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:: @@ -226,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 ebf93b8..e7c646d 100755 --- a/nodeenv.py +++ b/nodeenv.py @@ -46,8 +46,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' @@ -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( @@ -497,9 +491,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(): @@ -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)) @@ -957,7 +945,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')) @@ -1020,18 +1008,21 @@ def main(): logger.error('Installing system node.js on win32 is not supported!') exit(1) - global iojs_taken - global src_domain - - if opt.io: - iojs_taken = True - src_domain = "iojs.org" + global src_base_url + src_domain = None 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