From 4b0b7c02e6d2b05c699825bc1391c835feb9fc7e Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 5 Sep 2018 23:42:41 -0400 Subject: [PATCH] init --- README.md | 8 +++++ install.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ install_test.py | 35 +++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 README.md create mode 100755 install.py create mode 100755 install_test.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..f5a66a6 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Deno Binary Installer + +Downloads the latest Deno binary into $HOME/.deno/bin + +Usage: +``` +curl -sSf https://raw.githubusercontent.com/denoland/deno_install/master/install.py | python +``` diff --git a/install.py b/install.py new file mode 100755 index 0000000..81036d1 --- /dev/null +++ b/install.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +# Copyright 2018 the Deno authors. All rights reserved. MIT license. +from __future__ import print_function + +import io +import json +import os +import re +import shutil +import sys +import tempfile +import zipfile +import zlib + +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + +RELEASES_URL = "https://github.com/denoland/deno/releases/latest" +FILENAME_LOOKUP = { + "darwin": "deno_osx_x64.gz", + "linux": "deno_linux_x64.gz", # python3 + "linux2": "deno_linux_x64.gz", # python2 + "win32": "deno_win_x64.zip", + "cygwin": "deno_win_x64.zip" +} + + +def release_url(platform): + try: + filename = FILENAME_LOOKUP[platform] + except KeyError: + print("Unable to locate appropriate filename for", platform) + sys.exit(1) + + html = urlopen(RELEASES_URL).read().decode('utf-8') + urls = re.findall(r'href=[\'"]?([^\'" >]+)', html) + matching = [u for u in urls if filename in u] + + if len(matching) != 1: + print("Unable to find download url for", filename) + sys.exit(1) + + return "https://github.com" + matching[0] + + +def main(): + bin_dir = deno_bin_dir() + exe_fn = os.path.join(bin_dir, "deno") + + url = release_url(sys.platform) + print("Downloading", url) + compressed = urlopen(url).read() + + if url.endswith(".zip"): + with zipfile.ZipFile(io.BytesIO(compressed), 'r') as z: + with open(exe_fn, 'wb+') as exe: + exe.write(z.read('deno.exe')) + else: + # Note: gzip.decompress is not available in python2. + content = zlib.decompress(compressed, 15 + 32) + with open(exe_fn, 'wb+') as exe: + exe.write(content) + os.chmod(exe_fn, 0o744) + + print("DENO_EXE: " + exe_fn) + print("Now manually add %s to your $PATH" % bin_dir) + print("Example:") + print() + print(" echo export PATH=\"%s\":\\$PATH >> $HOME/.bash_profile" % bin_dir) + print() + + +def mkdir(d): + if not os.path.exists(d): + print("mkdir", d) + os.mkdir(d) + + +def deno_bin_dir(): + home = os.path.expanduser("~") + deno = os.path.join(home, ".deno") + mkdir(deno) + deno_bin = os.path.join(deno, "bin") + mkdir(deno_bin) + return deno_bin + + +if __name__ == '__main__': + main() diff --git a/install_test.py b/install_test.py new file mode 100755 index 0000000..0e1f482 --- /dev/null +++ b/install_test.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# Copyright 2018 the Deno authors. All rights reserved. MIT license. +import sys +import shutil +import os +import subprocess + +this_dir = os.path.dirname(os.path.realpath(__file__)) + + +def main(): + os.chdir(this_dir) + PATTERN = "DENO_EXE: " + home = os.path.expanduser("~") + expected_bin_dir = os.path.join(home, ".deno", "bin") + print "Testing install.py ... Expect deno installed to ", expected_bin_dir + if os.path.exists(expected_bin_dir): + shutil.rmtree(expected_bin_dir) + expected_fn = os.path.join(expected_bin_dir, "deno") + + cmd = [sys.executable, "install.py"] + out = subprocess.check_output(cmd, universal_newlines=True) + actual_fn = None + for line in out.splitlines(): + print line + if PATTERN in line: + print "set actual" + actual_fn = line[len(PATTERN):] + assert actual_fn == expected_fn, "actual %s != expected %s" % (actual_fn, + expected_fn) + assert os.path.exists(actual_fn) + + +if __name__ == '__main__': + main()