2018-07-08 02:24:29 -04:00
|
|
|
# Copyright 2018 Ryan Dahl <ry@tinyclouds.org>
|
|
|
|
# All rights reserved. MIT License.
|
|
|
|
import os
|
2018-07-25 04:17:44 -04:00
|
|
|
import shutil
|
|
|
|
import stat
|
2018-07-23 20:50:11 -04:00
|
|
|
import sys
|
2018-07-08 02:24:29 -04:00
|
|
|
import subprocess
|
|
|
|
|
2018-07-21 19:08:24 -04:00
|
|
|
executable_suffix = ".exe" if os.name == "nt" else ""
|
2018-07-25 04:17:44 -04:00
|
|
|
root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
2018-07-21 19:08:24 -04:00
|
|
|
|
2018-07-08 02:24:29 -04:00
|
|
|
|
2018-07-25 04:17:44 -04:00
|
|
|
def make_env(merge_env={}, env=None):
|
|
|
|
if env is None:
|
|
|
|
env = os.environ
|
|
|
|
env = env.copy()
|
|
|
|
for key in merge_env.keys():
|
|
|
|
env[key] = merge_env[key]
|
|
|
|
return env
|
|
|
|
|
|
|
|
|
|
|
|
def run(args, quiet=False, cwd=None, env=None, merge_env={}):
|
|
|
|
args[0] = os.path.normpath(args[0])
|
2018-07-16 22:40:42 -04:00
|
|
|
if not quiet:
|
|
|
|
print " ".join(args)
|
2018-07-25 04:17:44 -04:00
|
|
|
env = make_env(env=env, merge_env=merge_env)
|
2018-07-21 19:08:24 -04:00
|
|
|
shell = os.name == "nt" # Run through shell to make .bat/.cmd files work.
|
2018-07-23 20:50:11 -04:00
|
|
|
rc = subprocess.call(args, cwd=cwd, env=env, shell=shell)
|
|
|
|
if rc != 0:
|
|
|
|
sys.exit(rc)
|
2018-07-08 02:24:29 -04:00
|
|
|
|
|
|
|
|
2018-07-26 20:15:55 -04:00
|
|
|
def run_output(args, quiet=False, cwd=None, env=None, merge_env={}):
|
|
|
|
args[0] = os.path.normpath(args[0])
|
|
|
|
if not quiet:
|
|
|
|
print " ".join(args)
|
|
|
|
env = make_env(env=env, merge_env=merge_env)
|
|
|
|
shell = os.name == "nt" # Run through shell to make .bat/.cmd files work.
|
|
|
|
return subprocess.check_output(args, cwd=cwd, env=env, shell=shell)
|
|
|
|
|
|
|
|
|
2018-07-08 02:24:29 -04:00
|
|
|
def remove_and_symlink(target, name, target_is_dir=False):
|
|
|
|
try:
|
2018-07-08 13:14:55 -04:00
|
|
|
# On Windows, directory symlink can only be removed with rmdir().
|
|
|
|
if os.name == "nt" and os.path.isdir(name):
|
|
|
|
os.rmdir(name)
|
|
|
|
else:
|
|
|
|
os.unlink(name)
|
2018-07-08 02:24:29 -04:00
|
|
|
except:
|
|
|
|
pass
|
|
|
|
symlink(target, name, target_is_dir)
|
|
|
|
|
|
|
|
|
|
|
|
def symlink(target, name, target_is_dir=False):
|
|
|
|
if os.name == "nt":
|
|
|
|
import ctypes
|
|
|
|
CreateSymbolicLinkW = ctypes.windll.kernel32.CreateSymbolicLinkW
|
|
|
|
CreateSymbolicLinkW.restype = ctypes.c_ubyte
|
|
|
|
CreateSymbolicLinkW.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p,
|
|
|
|
ctypes.c_uint32)
|
|
|
|
|
2018-07-20 21:52:00 -04:00
|
|
|
# Replace forward slashes by backward slashes.
|
|
|
|
# Strangely it seems that this is only necessary for symlinks to files.
|
|
|
|
# Forward slashes don't cause any issues when the target is a directory.
|
|
|
|
target = target.replace("/", "\\")
|
2018-07-08 02:24:29 -04:00
|
|
|
flags = 0x02 # SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
|
|
|
|
if (target_is_dir):
|
|
|
|
flags |= 0x01 # SYMBOLIC_LINK_FLAG_DIRECTORY
|
|
|
|
if not CreateSymbolicLinkW(name, target, flags):
|
|
|
|
raise ctypes.WinError()
|
|
|
|
else:
|
|
|
|
os.symlink(target, name)
|
|
|
|
|
|
|
|
|
|
|
|
def touch(fname):
|
|
|
|
if os.path.exists(fname):
|
|
|
|
os.utime(fname, None)
|
|
|
|
else:
|
|
|
|
open(fname, 'a').close()
|
2018-07-23 12:44:27 -04:00
|
|
|
|
|
|
|
|
|
|
|
# Recursive search for files of certain extensions.
|
|
|
|
# (Recursive glob doesn't exist in python 2.7.)
|
|
|
|
def find_exts(directory, *extensions):
|
|
|
|
matches = []
|
|
|
|
for root, dirnames, filenames in os.walk(directory):
|
|
|
|
for filename in filenames:
|
|
|
|
for ext in extensions:
|
|
|
|
if filename.endswith(ext):
|
|
|
|
matches.append(os.path.join(root, filename))
|
|
|
|
break
|
|
|
|
return matches
|
2018-07-25 04:17:44 -04:00
|
|
|
|
|
|
|
|
|
|
|
# The Python equivalent of `rm -rf`.
|
|
|
|
def rmtree(directory):
|
|
|
|
# On Windows, shutil.rmtree() won't delete files that have a readonly bit.
|
|
|
|
# Git creates some files that do. The 'onerror' callback deals with those.
|
|
|
|
def rm_readonly(func, path, _):
|
|
|
|
os.chmod(path, stat.S_IWRITE)
|
|
|
|
func(path)
|
|
|
|
|
|
|
|
shutil.rmtree(directory, onerror=rm_readonly)
|
2018-07-26 20:15:55 -04:00
|
|
|
|
|
|
|
|
|
|
|
def build_mode():
|
|
|
|
if "DENO_BUILD_MODE" in os.environ:
|
|
|
|
return os.environ["DENO_BUILD_MODE"]
|
|
|
|
else:
|
|
|
|
return "debug"
|
|
|
|
|
|
|
|
|
|
|
|
# E.G. "out/debug"
|
|
|
|
def build_path():
|
|
|
|
if "DENO_BUILD_PATH" in os.environ:
|
|
|
|
return os.environ["DENO_BUILD_PATH"]
|
|
|
|
else:
|
|
|
|
return os.path.join(root_path, "out", build_mode())
|