From 478c1842c61d130e1a227136dc9b572385aa0b34 Mon Sep 17 00:00:00 2001 From: JohnnyChen Date: Mon, 17 Feb 2020 02:13:43 +0800 Subject: [PATCH] add upgrade flag to subcommand install it copies the root project of older julia version to the new one --- README.md | 20 ++++++++++------ jill/install.py | 62 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f3fed26..cb0a5d3 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ The Python fork of [JILL](https://github.com/abelsiqueira/jill) - Julia Installe * download *latest* Julia release from *nearest* mirror server. Check [sources](jill/config/sources.json) for the list of all registered mirrors. * install julia for Linux and MacOS (including nightly build: `latest`) +* manage multiple julia releases * easily set up a new release mirror ## Installation @@ -20,22 +21,25 @@ The Python fork of [JILL](https://github.com/abelsiqueira/jill) - Julia Installe Note that `Python >= 3.6` is required. -## Basic usage examples +## Usage examples for most users + +TL;DR `jill install [version]` covers most of your need. * download: - latest stable release for current system: `jill download` - latest `1.y` version: `jill download 1` - latest `1.3.z` version: `jill download 1.3` - - test releases: `jill download 1.4.0-rc1` + - temporary releases: `jill download 1.4.0-rc1` - from specific upstream: `jill download --upstream Official` - specific release version: `jill download --version 1.3.0` - specific system: `jill download --sys freebsd` - specific architecture: `jill download --arch i686` - download Julia to specific dir: `jill download --outdir another/dir` * install Julia for current system: - - system-wide: `sudo jill install` (make symlink in `/usr/bin`) - - only for current user: `jill install` (make symlink in `~/.local/bin`) + - system-wide for root: `sudo jill install` (make symlink in `/usr/bin`) + - only for current non-root user: `jill install` (make symlink in `~/.local/bin`) - specific version: `jill install 1.3` + - also copy root project from older julia environment: `jill install --upgrade` - don't need interactive promopt: `jill install --confirm` * check if there're new Julia versions: - `jill update` @@ -43,7 +47,9 @@ Note that `Python >= 3.6` is required. * find out all registered upstreams: `jill upstream` * check the not-so-elaborative documentation: `jill [COMMAND] -h` (e.g., `jill download -h`) -## Mirror +## For who are interested in setting up a new release mirror + +### Mirror `jill mirror [outdir]`: @@ -59,7 +65,7 @@ Repository [jill-mirror](https://github.com/johnnychen94/julia-mirror) provides start `docker-compose.yml` for you to start with, which is just a simple docker image built upon `jill mirror`. -## Register new mirror +### Register new mirror If it's an public mirror and you want to share it worldwide. You can add an entry to the [public registry](jill/config/sources.json), make a PR, then I will tag a new release for that. @@ -74,7 +80,7 @@ In the registry config file, a new mirror is a dictionary in the `upstream` fiel * `urls`: URL template to retrive Julia release * `latest_urls`: URL template to retrive the nightly build of Julia release -## Placeholders +### Placeholders Placeholders are used to register new mirrors. For example, the stable release url of the "Official" release server owned by [JuliaComputing](https://juliacomputing.com) is diff --git a/jill/install.py b/jill/install.py index 8be1a7f..0ba2ec2 100644 --- a/jill/install.py +++ b/jill/install.py @@ -12,6 +12,10 @@ import logging +def default_depot_path(): + return os.path.expanduser("~/.julia") + + def default_symlink_dir(): if getpass.getuser() == "root": # available to all users @@ -34,6 +38,23 @@ def default_install_dir(): raise ValueError(f"Unsupported system {system}") +def last_julia_version(version=None): + # version should follow semantic version syntax + def sort_key(ver): + return float(ver.lstrip("v")) + + version = float(f_minor_version(version)) if version else 999.999 + proj_versions = os.listdir(os.path.join(default_depot_path(), + "environments")) + proj_versions = sorted(filter(lambda ver: sort_key(ver) < version, + proj_versions), + key=sort_key) + if proj_versions: + return proj_versions[-1] + else: + return None + + def make_symlinks(src_bin, symlink_dir, version): if symlink_dir not in os.environ["PATH"].split(":"): logging.info(f"add {symlink_dir} to PATH") @@ -62,7 +83,30 @@ def make_symlinks(src_bin, symlink_dir, version): os.symlink(src_bin, linkpath) -def install_julia_linux(package_path, install_dir, symlink_dir, version): +def copy_root_project(version): + mver = f_minor_version(version) + old_ver = last_julia_version(version) + if old_ver is None: + logging.info( + f"Can't find available old root project for version f{version}") + return None + + env_path = os.path.join(default_depot_path(), "environments") + src_path = os.path.join(env_path, old_ver) + dest_path = os.path.join(env_path, f"v{mver}") + + if os.path.exists(dest_path): + bak_path = os.path.join(env_path, f"v{mver}.bak") + logging.info(f"move {dest_path} to {bak_path}") + shutil.move(dest_path, bak_path) + shutil.copytree(src_path, dest_path, dirs_exist_ok=False) + + +def install_julia_linux(package_path, + install_dir, + symlink_dir, + version, + upgrade): mver = f_minor_version(version) with TarMounter(package_path) as root: src_path = root @@ -74,10 +118,16 @@ def install_julia_linux(package_path, install_dir, symlink_dir, version): os.chmod(dest_path, 0o755) # issue 12 bin_path = os.path.join(dest_path, "bin", "julia") make_symlinks(bin_path, symlink_dir, version) + if upgrade: + copy_root_project(version) return True -def install_julia_mac(package_path, install_dir, symlink_dir, version): +def install_julia_mac(package_path, + install_dir, + symlink_dir, + version, + upgrade): assert os.path.splitext(package_path)[1] == ".dmg" with DmgMounter(package_path) as root: # mounted image contents: @@ -93,6 +143,8 @@ def install_julia_mac(package_path, install_dir, symlink_dir, version): bin_path = os.path.join(dest_path, "Contents", "Resources", "julia", "bin", "julia") make_symlinks(bin_path, symlink_dir, version) + if upgrade: + copy_root_project(version) return True @@ -100,6 +152,7 @@ def install_julia(version=None, *, install_dir=None, symlink_dir=None, update=False, + upgrade=False, upstream=None, keep_downloads=False, confirm=False): @@ -108,13 +161,14 @@ def install_julia(version=None, *, Arguments: version: Option examples: 1, 1.2, 1.2.3, latest. - By default it's the latest stable release. See also `jill update` + By default it's the latest stable release. See also `jill update`. upstream: manually choose a download upstream. For example, set it to "Official" if you want to download from JuliaComputing's s3 buckets. update: add `--update` to update release info for incomplete version string (e.g., `1.0`) before downloading. + upgrade: True to also copy the root environment from older julia version. keep_downloads: True to not remove downloaded releases. confirm: add `--confirm` to skip interactive prompt. """ @@ -150,7 +204,7 @@ def install_julia(version=None, *, else: raise ValueError(f"Unsupported system {system}") - installer(package_path, install_dir, symlink_dir, version) + installer(package_path, install_dir, symlink_dir, version, upgrade) if not keep_downloads: logging.info("remove downloaded files")