예제 #1
0
파일: __main__.py 프로젝트: cppddz/cook
def script_get_book():
    if el.file_exists_p("Cookbook.py"):
        return os.path.realpath("Cookbook.py")
    elif el.file_exists_p("cook/Cookbook.py"):
        return os.path.realpath("cook/Cookbook.py")
    else:
        raise RuntimeError("No Cookbook.py or cook/Cookbook.py found")
예제 #2
0
def compile_and_run(recipe, source_file):
    class_file = re.sub("java$", "class", source_file)
    assert el.file_exists_p(source_file)
    source = el.file_name_nondirectory(source_file)
    path = el.file_name_directory(source_file)
    name = el.file_name_sans_extension(source)
    res = []
    if (not el.file_exists_p(class_file) or
            el.file_newer_than_file_p(source_file, class_file)):
        res += [lf("javac {source_file}")]
    res += [lf("java -cp {path} {name}")]
    return res
예제 #3
0
def git_clone(url, target_dir, commit=None):
    target_dir = el.expand_file_name(target_dir)
    if el.file_exists_p(target_dir):
        print(lf("{target_dir}: OK"))
    else:
        gdir = el.expand_file_name(target_dir)
        pdir = el.file_name_directory(gdir)
        if not el.file_exists_p(pdir):
            el.make_directory(pdir)
        (_, gdir) = el.parse_fname(gdir)
        sc("git clone --recursive {url} {gdir}")
        if commit:
            sc("cd {gdir} && git reset --hard {commit}")
예제 #4
0
def clone(remote, local):
    res = []
    local = el.expand_file_name(local)
    if el.file_exists_p(local):
        if el.file_exists_p(el.expand_file_name(".git", local)):
            res += ["cd " + local, "git pull"]
        else:
            raise RuntimeError("Directory exists and is not a git repo", local)
    else:
        (bd, repo) = os.path.split(local)
        el.make_directory(bd)
        res += [lf("cd {bd}"), lf("git clone {remote} {repo}")]
    return res
예제 #5
0
def cp(fr, to):
    if el.file_exists_p(to) and file_equal(fr, to):
        print(lf("{to}: OK"))
        return False
    else:
        el.sc(sudo("cp '{fr}' '{to}'", to))
        return True
예제 #6
0
def install_package(package, url=None):
    if isinstance(package, list):
        res = False
        for p in package:
            res |= install_package(p, url)
        return res
    user = sc("whoami")
    su = "" if user == "root" else "sudo "
    if el.file_exists_p("/usr/bin/dpkg"):
        if package_installed_p_dpkg(package):
            print(lf("{package}: OK"))
            return False
        else:
            if url is None:
                bash(
                    lf("{su}apt-get update && DEBIAN_FRONTEND=noninteractive {su}apt-get install -y {package}"
                       ))
            else:
                fname = wget(url)
                bash(lf("{su}dpkg -i {fname}"))
            return True
    else:
        if package_installed_p_yum(package):
            print(lf("{package}: OK"))
            return False
        else:
            if url is None:
                bash(
                    lf("{su}yum update -y && {su}yum upgrade -y && {su}yum install -y '{package}'"
                       ))
            else:
                fname = wget(url)
                bash(lf("{su}yum localinstall -y {fname}"))
            return True
예제 #7
0
def patch(fname, patches):
    """Patch FNAME applying PATCHES.
    Each PATCH in PATCHES is in diff -u format.
    Each line in PATCH starts with [+- ].
    [ ] lines are the optional start and end context.
    [-] lines are expected to exist in the file and will be removed.
    [+] lines will be added to the file after [-] lines are removed.

    PATCH lines should be in contiguous order: optional start context,
    [-] lines, [+] lines, optional end context.

    If PATCH was already applied for FNAME, it will be ignored.
    PATCHES can also be a file name of a "diff -u" output.
    """
    (host, name) = parse_fname(fname)
    patches = parse_patches(patches)
    if el.file_exists_p(fname):
        txt = el.slurp(fname)
    else:
        assert not any([
            re.search("^\\-", patch, flags=re.MULTILINE) for patch in patches
        ])
        el.sc("touch {name}")
        txt = ""
    no_change = True
    for ptch in patches:
        patch_lines = el.delete("", ptch.splitlines())
        chunk_before = render_patch(patch_lines, True)
        chunk_after = render_patch(patch_lines, False)
        if chunk_before == "":
            if not re.search("^" + re.escape(chunk_after), txt, re.MULTILINE):
                no_change = False
                if not (txt == "" or txt[-1] == "\n"):
                    txt += "\n"
                txt += chunk_after + "\n"
        elif (re.search("^" + re.escape(chunk_before), txt, re.MULTILINE) and
              not re.search("^" + re.escape(chunk_after), txt, re.MULTILINE)):
            no_change = False
            txt = re.sub("^" + re.escape(chunk_before),
                         chunk_after,
                         txt,
                         flags=re.MULTILINE)
        else:
            # either already patched or fail
            assert chunk_after in txt
    if no_change:
        print(fname + ": OK")
        return False
    else:
        print(fname + ": Patch")
        with el.hostname(None):
            el.barf("/tmp/insta.txt", txt)
        if host is not None:
            cmd = lf("scp /tmp/insta.txt {host}:{name}")
        else:
            cmd = sudo(lf("cp /tmp/insta.txt {name}"), name)
        with el.hostname(None):
            bash(cmd, desc=(host, "edit " + name))
        return True
예제 #8
0
def cp(fr, to):
    fr = el.expand_file_name(fr)
    to = el.expand_file_name(to)
    if el.file_exists_p(to) and file_equal(fr, to):
        print(lf("{to}: OK"))
        return False
    else:
        el.sc(sudo("cp '{fr}' '{to}'", to))
        return True
예제 #9
0
파일: rust.py 프로젝트: zed/cook
def compile_and_run(src_file):
    exe_file = el.file_name_sans_extension(src_file)
    if (el.file_exists_p(exe_file) and
            el.file_newer_than_file_p(exe_file, src_file)):
        return [lf("./{exe_file}")]
    else:
        return [
            lf("rustc {src_file}"),
            lf("./{exe_file}")]
예제 #10
0
def get_change_time(fname):
    fname = el.expand_file_name(fname)
    if el.file_directory_p(fname):
        git_dir = el.expand_file_name(".git", fname)
        if el.file_exists_p(git_dir):
            return float(git.mtime(fname).strftime("%s"))
        else:
            raise RuntimeError("Directory is not a git repo")
    else:
        return os.path.getctime(fname)
예제 #11
0
def echo(fr_text, to):
    if el.file_exists_p(to) and fr_text == el.slurp(to):
        print(lf("{to}: OK"))
        return False
    else:
        host = el.HOST
        with el.hostname(None):
            el.sc("echo '{fr_text}' | ssh '{host}' -T 'cat > {to}'",
                  desc=(host, "write " + to))
            return True
예제 #12
0
def book_config(book):
    rc_file = el.expand_file_name("~/.cook.d/__config__.py")
    if el.file_exists_p(rc_file):
        mod = imp.load_source("book_config", rc_file)
        config = mod.config
        if book in config:
            return config[book]
        elif "*" in config:
            return config["*"]
    return {}
예제 #13
0
def ln(fr, to):
    fr_full = el.expand_file_name(fr)
    if not el.file_exists_p(fr_full):
        raise RuntimeError("File doesn't exist", fr_full)
    to_full = el.expand_file_name(to)
    if el.file_exists_p(to_full):
        if symlink_p(to_full):
            print(lf("{to_full}: OK"))
        else:
            if file_equal(fr_full, to_full):
                print(lf("{to_full} exists, contents equal"))
            else:
                print(lf("{to_full} exists, contents NOT equal"))
    else:
        if el.HOST:
            cmd = lf("ln -s {fr} {to}")
        else:
            fr_abbr = os.path.relpath(fr_full, os.path.dirname(to))
            cmd = sudo(lf("ln -s {fr_abbr} {to_full}"), to_full)
        bash(cmd)
예제 #14
0
def wget(url, download_dir="/tmp/"):
    if download_dir[:-1] == "/":
        fname = url.split("/")[-1]
        full_name = el.expand_file_name(fname, download_dir)
    else:
        full_name = download_dir
    if el.file_exists_p(full_name):
        print(lf("{full_name}: OK"))
    else:
        bash(lf("wget '{url}' -O {full_name}"))
        return full_name
예제 #15
0
def read_layouts():
    r = {}
    config_file = "~/.config/xkb-indicator/xkb-indicator.ini"
    if el.file_exists_p(config_file):
        txt = el.slurp(config_file)
        m = re.search("layouts=(.*)", txt)
        if m:
            layouts = m.group(1).split(",")
            assert len(
                layouts
            ) == 2, "Only two layouts are supported currently. See " + config_file
            return layouts
    return ["xx", "ua"]
예제 #16
0
def compile_and_run_cc(inputs,
                       std="c++11",
                       flags="",
                       idirs=(),
                       libs=(),
                       cc="g++"):
    """Compile INPUTS together into an executable and run it.

    INPUTS is a list of source files, headers and libraries.
    The executable is named after the first source file.
    Any file that doesn't exist is assumed to be a library.
    """
    if isinstance(inputs, list):
        main_file = inputs[0]
    else:
        main_file = inputs
    assert el.file_exists_p(main_file)
    sources = el.re_filter("(cc|cpp|h|hh|hpp)$", inputs)
    diff = set(inputs) - set(sources)
    libs_inl = [x for x in inputs if x in diff]
    libs_str = " " + " ".join(["-l" + lib for lib in libs_inl])
    lib_dirs = set(map(el.file_name_directory, libs))
    lflags = list(map(lib_name, libs))
    libs_str += " " + " ".join(["-L" + d for d in lib_dirs] + lflags)
    exe_file = re.sub("cc$", "e", main_file)
    res = []
    flags += " " + " ".join(["-I" + d for d in idirs])
    if (not el.file_exists_p(exe_file) or any([
            el.file_newer_than_file_p(f, exe_file)
            for f in sources + [cook.script_get_book()[0]]
    ])):
        ccmd = lf("g++ -g -O2 -std={std} {flags} -o {exe_file} ") + " ".join(
            sources) + libs_str
        res += [ccmd]
    if lib_dirs:
        res += ["export LD_LIBRARY_PATH=" + ":".join(lib_dirs)]

    res += [lf("./{exe_file}")]
    return res
예제 #17
0
def modules(full=False, match=False):
    cook_dir = el.file_name_directory(recipes.__file__)
    cook_modules = el.directory_files(cook_dir, full, match)
    user_dir = el.expand_file_name("~/.cook.d")
    if el.file_exists_p(user_dir):
        df = el.directory_files(user_dir, full, match)
        user_modules = [
            f for f in df if os.path.isfile(el.expand_file_name(f, user_dir))
            and os.path.splitext(f)[1] == ".py"
        ]
    else:
        user_modules = []
    cook_modules += user_modules
    return list(filter(lambda s: not re.search("__", s), cook_modules))
예제 #18
0
def make(target, cmds, deps=()):
    if (el.file_exists_p(target) and \
        all([get_change_time(target) > get_change_time(dep) for dep in deps])):
        print(lf("{target}: OK"))
        return False
    else:
        if isinstance(cmds, str):
            cmds = [cmds]
        elif callable(cmds):
            cmds(target)
            return True
        fcmds = []
        for cmd in cmds:
            cmd1 = re.sub("\\$@", target, cmd)
            cmd2 = re.sub("\\$\\^", " ".join([shlex.quote(dep) for dep in deps]), cmd1)
            cmd3 = re.sub("\\$<", shlex.quote(deps[0]), cmd2) if deps else cmd2
            if el.sc_hookfn:
                el.sc_hookfn(cmd3)
            fcmds.append(cmd3)
        bash(fcmds)
        return True
예제 #19
0
def install_root_cert(certfile, certname=None):
    """Install root certificate to certificate trust store of applications using NSS"""
    install_package("libnss3-tools")
    name_crt = el.file_name_nondirectory(certfile) if certname is None else certname
    # Firefox and Chromium
    if not el.file_exists_p("/tmp/cert9.db.done"):
        dbs = el.sc_l("find ~/ -name cert9.db 2>/dev/null || true")
        for db in dbs:
            certdir = el.file_name_directory(db)
            el.scb("certutil -A -n '{name_crt}' -t 'TCu,Cu,Tu' -i {certfile} -d sql:{certdir}")
        el.barf("/tmp/cert9.db.done", "")
    # curl
    cp_cmd = cp_host if el.HOST else cp
    fname_crt = lf("/usr/local/share/ca-certificates/{name_crt}")
    cp_cmd(certfile, fname_crt)
    chmod(fname_crt, "644")
    name_pem = el.file_name_sans_extension(name_crt) + ".pem"
    fname_pem = lf("/etc/ssl/certs/{name_pem}")
    make(fname_pem, sudo("update-ca-certificates"))
    # wget
    install_package("ca-certificates")
    patch("/etc/wgetrc", ["+ca_directory=/etc/ssl/certs"])
예제 #20
0
def get_image(i):
    if i == "." and el.file_exists_p("params.json"):
        js = json.load(open("params.json", "r"))
        return js["docker_url"] + ":" + js["docker_version"]
    else:
        return i
예제 #21
0
#* Imports
import sys
import shutil
import pycook.elisp as el
sc = el.sc
lf = el.lf

#* Constants
sudo_cmd = "sudo -H " if el.file_exists_p("/usr/bin/sudo") else "su -c"


#* Functions
def sudo(cmd):
    return sudo_cmd + cmd


def get_pip():
    is_sudo = shutil.which("cook").find("/usr/local/bin") != -1
    if sys.version_info.major == 3:
        pip = "pip3"
    else:
        pip = "pip"
    if is_sudo:
        return sudo(pip)
    else:
        return pip


def package_installed_p(package):
    try:
        s = sc(get_pip() + " show " + package)
예제 #22
0
def barf(fname, text):
    if el.file_exists_p(fname) and text == el.slurp(fname):
        print(lf("{fname}: OK"))
    else:
        quoted_text = shlex.quote(text)
        bash(lf("echo {quoted_text} | sudo tee {fname} > /dev/null"))
예제 #23
0
def test_interactive(recipe):
    elfs = ["orca.el", "targets/server-restart.el"]
    plain = "../swiper/targets/plain.el"
    if el.file_exists_p("../swiper/targets/plain.el"):
        elfs.append(plain)
    return [" ".join(["emacs -Q"] + ["-l " + p for p in elfs])]
예제 #24
0
def repo_p(d):
    return el.file_exists_p(el.expand_file_name(".git", d))