Пример #1
0
def install_pack(pack):
    """Installs a single pack"""

    (pack, sep, pconfig) = pack.partition(":")

    pack_setup = get_pack_setup(pack)
    pack_dir = get_pack_dir(pack)

    if not pack_setup:
        return False

    # Create ext/ if it does not exist.
    if not os.path.isdir(lmh_locate("ext")):
        os.mkdir(lmh_locate("ext"))

    if pack_setup.is_installed(pack_dir):
        err("Pack", pack, "is already installed, use --update to update. ")
        return False

    try:
        return pack_setup.install(pack_dir, pconfig)
    except classes.UnsupportedAction:
        err("Pack", pack,
            "does not support installing. You may want to --update the pack?")
        return False
Пример #2
0
def match_repo(repo, root=os.getcwd(), abs=False, existence=True):
    """Matches a single specefier to a repository. """

    # 1) Resolve to absolute path repo (via root)
    # 2) If it is (inside) a repository, return that repository
    # 3) If not, try to repeat 1) and 2) with root = data_dir
    # 4) If that fails, return None

    # make sure the root is absolute
    root = os.path.abspath(root)

    # If repo is empty, make sure we use the current directory.
    if repo == "":
        repo = os.getcwd()

    # try the full repo_path
    repo_path = os.path.join(root, repo)

    if is_repo_dir(repo_path, existence) or is_in_repo(repo_path):
        # figure out the path to the repository root
        repo_path = find_repo_dir(repo_path, existence)
        if repo_path:
            if abs:
                # return the absolute path to the repo
                return repo_path
            else:
                # return just the repo name, determined by the relative name
                return os.path.relpath(repo_path, os.path.abspath(lmh_locate("content")))
    if not (root == os.path.abspath(lmh_locate("content"))):
        #if the root is not already the data_dir, try that
        return match_repo(repo, root=lmh_locate("content"), abs=abs,existence=existence)
    else:
        # nothing found
        return None
Пример #3
0
    def match_repo_name(r):

        # make an absolute path
        # this will also work with globs
        names = os.path.abspath(os.path.join(root, r))

        # it is not inside the data directory
        # so try again next time
        if not is_in_data(names):
            return True

        # find the relative path of it to the root.
        names = os.path.relpath(
            os.path.abspath(names),
            lmh_locate("content")
        )

        # make sure everything ends with a slash
        # so that we can count properly
        if names[-1] != "/":
            names += "/"

        # Now figure out which level we are at
        # by counting slashes
        num_slashes = 0
        for c in names:
            # count the slashes
            # by increasing the level.
            if c == "/":
                num_slashes += 1


        # if we have no slashes
        # we are toplevel
        # and can pretty much exit everything
        if names == "./":
            names = lmh_locate("content", "*", "*")

        # if we have 1 slash
        # we are one level deep
        elif num_slashes == 1:
            names = lmh_locate("content", names, "*")
        else:
            names = lmh_locate("content", names)

        # now expand with the help of globs
        names = glob.glob(names)

        # and check if they exist
        names = list(filter(is_repo, names))

        # if we found something
        # we should through the item
        if len(names) > 0:
            results.update(names)
            return False
        else:
            return True
Пример #4
0
def find_repo_subdirs(path):
    """
        Returns the absolute path to the all repositories contained in PATH.

        @param {string} path - Path to check

        @returns {string[]}
    """

    # path needs to be a directory
    if not os.path.isdir(path):
        return []

    # We are not inside the data directory
    # so we need to return nothing
    if not is_in_data(path):
        return []

    # If we can find the current repository path
    # we can return it.
    repo_path = find_repo_dir(path)
    if repo_path:
        return [repo_path]

    # Find the relative path from the root to the current directory
    name = os.path.relpath(os.path.abspath(path), lmh_locate("content"))

    # make sure everything ends with a slash
    # so that we can count properly
    if name[-1] != "/":
        name += "/"

    # Now figure out which level we are at
    # by counting slashes
    num_slashes = 0
    for c in name:
        # count the slashes
        # by increasing the level.
        if c == "/":
            num_slashes += 1

    # if we have no slashes
    # we are toplevel
    if name == "./":
        name = lmh_locate("content", "*", "*")
    # if we have 1 slash
    # we are one level deep
    elif num_slashes == 1:
        name = lmh_locate("content", name, "*")
    # else something is wrong
    # and we are nowhere
    else:
        return []

    # now we can match the paths via glob.glob
    # and check that they exist
    return list(filter(is_repo, glob.glob(name)))
Пример #5
0
    def match_repo_name(r):

        # make an absolute path
        # this will also work with globs
        names = os.path.abspath(os.path.join(root, r))

        # it is not inside the data directory
        # so try again next time
        if not is_in_data(names):
            return True

        # find the relative path of it to the root.
        names = os.path.relpath(os.path.abspath(names), lmh_locate("content"))

        # make sure everything ends with a slash
        # so that we can count properly
        if names[-1] != "/":
            names += "/"

        # Now figure out which level we are at
        # by counting slashes
        num_slashes = 0
        for c in names:
            # count the slashes
            # by increasing the level.
            if c == "/":
                num_slashes += 1

        # if we have no slashes
        # we are toplevel
        # and can pretty much exit everything
        if names == "./":
            names = lmh_locate("content", "*", "*")

        # if we have 1 slash
        # we are one level deep
        elif num_slashes == 1:
            names = lmh_locate("content", names, "*")
        else:
            names = lmh_locate("content", names)

        # now expand with the help of globs
        names = glob.glob(names)

        # and check if they exist
        names = list(filter(is_repo, names))

        # if we found something
        # we should through the item
        if len(names) > 0:
            results.update(names)
            return False
        else:
            return True
Пример #6
0
def get_metainf_lines(package):
    """
        Gets the lines of the meta-inf file.

        @param package {string} Package to read meta-inf lines form.

        @returns {string[]}
    """

    # Find the package root directory.
    package_dir = find_repo_dir(lmh_locate("content", package))

    # Check that repository is installed.
    if not package_dir:
        err("Repository", package, "is not installed. Failed to read META-INF. ")
        return []

    # Read the path to meta_inf
    meta_inf_path = os.path.join(package_dir, "META-INF", "MANIFEST.MF")

    try:
        # Try and read the file lines
        return read_file_lines(meta_inf_path)
    except:
        # File is not readable, silently fail.
        return []
Пример #7
0
def write_deps(dirname, deps):
    """Writes dependencies into a given module. """

    f = lmh_locate("content", match_repo(dirname), "META-INF", "MANIFEST.MF")
    n = re.sub(r"dependencies: (.*)", "dependencies: "+",".join(deps), read_file(f))
    write_file(f, n)
    std("Wrote new dependencies to", f)
Пример #8
0
def get_metainf_lines(package):
    """
        Gets the lines of the meta-inf file.

        @param package {string} Package to read meta-inf lines form.

        @returns {string[]}
    """

    # Find the package root directory.
    package_dir = find_repo_dir(lmh_locate("content", package))

    # Check that repository is installed.
    if not package_dir:
        err("Repository", package,
            "is not installed. Failed to read META-INF. ")
        return []

    # Read the path to meta_inf
    meta_inf_path = os.path.join(package_dir, "META-INF", "MANIFEST.MF")

    try:
        # Try and read the file lines
        return read_file_lines(meta_inf_path)
    except:
        # File is not readable, silently fail.
        return []
Пример #9
0
def get_template(name):
    """
    Gets a template file with the given name
    """

    # TODO: Find out why this is unused and if we still need it.
    return read_file(lmh_locate("bin", "templates", name))
Пример #10
0
def is_repo_dir(path, existence=True):
    """
        Checks if a directory contains a MathHub repository.

        Optimised to exit as soon as possible when the directory is not
        a repository.

        @param path {string} Path to check.
        @param existence {boolean} Do we do a theoretical test only or do we check for existence as well?

        @returns {boolean}
    """

    if re.match('^[^\/]+\/[^\/]+$', path):
        # it is already a name.
        name = path
    else:
        # it is not a name, so we need to find the relative_path.
        name = os.path.relpath(os.path.abspath(path), lmh_locate("content"))

        # if the name ends with a /, remove it.
        if name.endswith("/"):
            name = name[:-1]

        # if the path does not match, we need to exit.
        if not re.match('^[^\/]+\/[^\/]+$', name):
            return False

    # if we need existence, check it is a git directory
    if existence:
        return is_repo(path)

    # we have passed all the tests
    return True
Пример #11
0
def main(argv=sys.argv[1:]):
    """Calls the main program with given arguments. """

    # Load commands + aliases
    commands = json.loads(read_file(lmh_locate("lib", "data",
                                               "commands.json")))
    aliases = json.loads(read_file(lmh_locate("lib", "data", "aliases.json")))

    parser = create_parser(submods, commands, aliases)

    if len(argv) == 0:
        parser.print_help()
        return

    # parse arguments
    (args, unknown) = parser.parse_known_args(argv)

    # do the quiet stuff.
    if args.quiet:
        lmh.lib.io.__supressStd__ = True
        lmh.lib.io.__supressErr__ = True
    if args.non_interactive:
        lmh.lib.io.__supressIn__ = True

    # No action.
    if args.action == None:
        parser.print_help()
        return

    # an alias, so change the arguments.
    if args.action in aliases:

        # new argvs
        argv = shlex.split(aliases[args.action]) + unknown

        # and re-parse
        (args, unknown) = parser.parse_known_args(argv)

    try:
        if not submods[args.action].allow_unknown and len(unknown) > 0:
            err("Too many arguments. ")
            return False
    except Exception as e:
        err(e)

    # run normally.
    return submods[args.action].do(args, unknown)
Пример #12
0
    def do_install(self, pack_dir, sstring):
        """Installs a git controlled package. """
        (source, branch) = get_item_source(sstring, self.dsource, self.dbranch, self.name)

        try:
            # git clone first
            if not git_clone(lmh_locate("ext"), source, pack_dir):
                return False

            # do the checkout
            if branch != "":
                return git_do(lmh_locate("ext", pack_dir), "checkout", branch)
            else:
                return True
        except:
            err("git clone failed to clone", source, ". Check your network connection. ")
            return False
Пример #13
0
def git_version():
    """
    Returns the current git version of lmh as a string or None
    """
    try:
        return do_data(lmh_locate(), "rev-parse", "HEAD")[0].rstrip()
    except:
        return None
Пример #14
0
def main(argv=sys.argv[1:]):
    """Calls the main program with given arguments. """

    # Load commands + aliases
    commands = json.loads(read_file(lmh_locate("lib", "data", "commands.json")))
    aliases = json.loads(read_file(lmh_locate("lib", "data", "aliases.json")))

    parser = create_parser(submods, commands, aliases)

    if len(argv) == 0:
        parser.print_help()
        return

    # parse arguments
    (args, unknown) = parser.parse_known_args(argv)

    # do the quiet stuff.
    if args.quiet:
        lmh.lib.io.__supressStd__ = True
        lmh.lib.io.__supressErr__ = True
    if args.non_interactive:
        lmh.lib.io.__supressIn__ = True

    # No action.
    if args.action == None:
        parser.print_help()
        return

    # an alias, so change the arguments.
    if args.action in aliases:

        # new argvs
        argv = shlex.split(aliases[args.action]) + unknown

        # and re-parse
        (args, unknown) = parser.parse_known_args(argv)

    try:
        if not submods[args.action].allow_unknown and len(unknown) > 0:
            err("Too many arguments. ")
            return False
    except Exception as e:
        err(e)

    # run normally.
    return submods[args.action].do(args, unknown)
Пример #15
0
def git_version():
    """
    Returns the current git version of lmh as a string or None
    """
    try:
        return do_data(lmh_locate(), "rev-parse", "HEAD")[0].rstrip()
    except:
        return None
Пример #16
0
def match_repo_args(spec, all=False, abs=True):
    """Matches repository arguments to an actual list of repositories"""

    if all:
        return match_repos(lmh_locate("content"), abs=abs)
    elif len(spec) == 0:
        return match_repos(".", abs=abs)
    else:
        return match_repos(spec, abs=abs)
Пример #17
0
def locate_files(path):
    """
        Finds all files matching a specific specification.
        @param path Path to find files in
    """

    # if we are outside data_dir, we return.
    if path.startswith(os.path.abspath(lmh_locate())) and not path.startswith(
            os.path.abspath(lmh_locate("content"))):
        return []

    # fill these modules.
    modules = []

    # Make sure we are inside the source directory.
    if os.path.relpath(lmh_locate("content"), path) == "../..":
        path = path + "/source"

    # Make it an absolute path.
    path = os.path.abspath(path)

    # if it is a file, we are done.
    if os.path.isfile(path):
        return [path]

    # if it is not a directory, return.
    if not os.path.isdir(path):
        return []

    # find all files and folders.
    objects = [os.path.abspath(path + "/" + f) for f in os.listdir(path)]
    files = filter(lambda f: os.path.isfile(f), objects)
    folders = filter(lambda f: os.path.isdir(f), objects)

    # HACK out the tikz directories.
    folders = filter(lambda f: not f.split("/")[-1] in folder_exclude_list,
                     folders)
    modules = reduce([os.path.abspath(file) for file in files])

    # and go into subdirectories.
    modules.extend(reduce([locate_files(folder) for folder in folders]))

    # return the modules.
    return modules
Пример #18
0
 def my_excepthook(exctype, value, tb):
     if exctype == KeyboardInterrupt:
         return
     e = ''.join(traceback.format_exception(exctype, value, tb))
     err(e)
     err("lmh seems to have crashed with %s"%exctype)
     err("a report will be generated in ")
     s = "cwd = {0}\n args = {1}\n".format(cwd, sys.argv)
     s = s + e
     write_file(lmh_locate("logs", time.strftime("%Y-%m-%d-%H-%M-%S.log")), s)
Пример #19
0
def locate_compile_target(path, try_root= True):
    """
        Finds all targets to be compiled. (Files AND Folders inside source/)
        @param path Path to find files in
    """
    spec = path

    # if we are not inside the data directory, return.
    if path.startswith(os.path.abspath(lmh_locate())) and not path.startswith(os.path.abspath(lmh_locate("content"))):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)
        return []

    # If we are inside the root, go inside the folder.
    relpath = os.path.relpath(lmh_locate("content"), os.path.realpath(path))
    if relpath == "../..":
        path = path + "/source"
    elif not relpath.endswith("../.."):
        return reduce([(locate_compile_target(p)) for p in find_repo_subdirs(path)])
    # Get the absolute path.
    path = os.path.realpath(path)

    # If it does not exist, return.
    if not os.path.isfile(path) and not os.path.isdir(path):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Could not find anything matching ", "'"+spec+"'")
        return []

    # find the repository dir.
    repo_dir = find_repo_dir(path, existence=True)
    repo_name = os.path.relpath(repo_dir, lmh_locate("content"))
    if repo_dir == False:
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Matching item to ", "'"+spec+"'", "are outside of repository. ")
        return []

    # Find the source directory and get a relative path
    repos_src_dir = os.path.join(repo_dir, "source")
    path = os.path.relpath(path, repos_src_dir)

    # if we need to go up, we are not in source
    if path.startswith("../"):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Matching item to", "'"+spec+"'", "are outside of the source directory. ")
        return []

    # return the name of the repository and the path inside the repository.
    return [(repo_name, path)]
Пример #20
0
def locate_files(path):
    """
        Finds all files matching a specific specification.
        @param path Path to find files in
    """

    # if we are outside data_dir, we return.
    if path.startswith(os.path.abspath(lmh_locate())) and not path.startswith(os.path.abspath(lmh_locate("content"))):
        return []

    # fill these modules.
    modules = []

    # Make sure we are inside the source directory.
    if os.path.relpath(lmh_locate("content"), path) == "../..":
        path = path + "/source"

    # Make it an absolute path.
    path = os.path.abspath(path)


    # if it is a file, we are done.
    if os.path.isfile(path):
        return [path]

    # if it is not a directory, return.
    if not os.path.isdir(path):
        return []

    # find all files and folders.
    objects = [os.path.abspath(path + "/" + f) for f in os.listdir(path)]
    files = filter(lambda f:os.path.isfile(f), objects)
    folders = filter(lambda f:os.path.isdir(f), objects)

    # HACK out the tikz directories.
    folders = filter(lambda f:not f.split("/")[-1] in folder_exclude_list, folders)
    modules = reduce([os.path.abspath(file) for file in files])

    # and go into subdirectories.
    modules.extend(reduce([locate_files(folder) for folder in folders]))

    # return the modules.
    return modules
Пример #21
0
def is_installed(package):
    """
        Checks if a repository is installed locally.

        @param package {string} Package to check.

        @returns {boolean}
    """

    return is_repo_dir(lmh_locate("content", package))
Пример #22
0
def is_installed(package):
    """
        Checks if a repository is installed locally.

        @param package {string} Package to check.

        @returns {boolean}
    """

    return is_repo_dir(lmh_locate("content", package))
Пример #23
0
def is_in_data(path):
    """
        Checks if a directory is contained within the data directory.

        @param path {string} Path to check.

        @returns {boolean}
    """

    return os.path.abspath(path).startswith(lmh_locate("content"))
Пример #24
0
def is_in_data(path):
    """
        Checks if a directory is contained within the data directory.

        @param path {string} Path to check.

        @returns {boolean}
    """

    return os.path.abspath(path).startswith(lmh_locate("content"))
Пример #25
0
 def my_excepthook(exctype, value, tb):
     if exctype == KeyboardInterrupt:
         return
     e = ''.join(traceback.format_exception(exctype, value, tb))
     err(e)
     err("lmh seems to have crashed with %s" % exctype)
     err("a report will be generated in ")
     s = "cwd = {0}\n args = {1}\n".format(cwd, sys.argv)
     s = s + e
     write_file(lmh_locate("logs", time.strftime("%Y-%m-%d-%H-%M-%S.log")),
                s)
Пример #26
0
def match_repo(repo, root=os.getcwd(), abs=False, existence=True):
    """Matches a single specefier to a repository. """

    # 1) Resolve to absolute path repo (via root)
    # 2) If it is (inside) a repository, return that repository
    # 3) If not, try to repeat 1) and 2) with root = data_dir
    # 4) If that fails, return None

    # make sure the root is absolute
    root = os.path.abspath(root)

    # If repo is empty, make sure we use the current directory.
    if repo == "":
        repo = os.getcwd()

    # try the full repo_path
    repo_path = os.path.join(root, repo)

    if is_repo_dir(repo_path, existence) or is_in_repo(repo_path):
        # figure out the path to the repository root
        repo_path = find_repo_dir(repo_path, existence)
        if repo_path:
            if abs:
                # return the absolute path to the repo
                return repo_path
            else:
                # return just the repo name, determined by the relative name
                return os.path.relpath(repo_path,
                                       os.path.abspath(lmh_locate("content")))
    if not (root == os.path.abspath(lmh_locate("content"))):
        #if the root is not already the data_dir, try that
        return match_repo(repo,
                          root=lmh_locate("content"),
                          abs=abs,
                          existence=existence)
    else:
        # nothing found
        return None
Пример #27
0
def find_and_replace_file(file, match, replace, replace_match = None):
    """Finds and replaces a single file. """

    if len(match) != len(replace):
        err("Find and Replace patterns are not of the same length. ")
        return False

    # Compile thex regexp
    try:
        match_regex = [re.compile(m) for m in match]
    except Exception as e:
        err(e)
        err("Unable to compile regular expressions. ")
        return False

    # get the repository
    repo = os.path.relpath(find_repo_dir(file), lmh_locate("content"))

    # We did nothing yet
    did = False
    if replace_match == None:
        def replace_match(match, replace):
            # TODO: Migrate this to the parent scope.
            # did = True

            # Make a template,
            replacer_template = {}
            replacer_template["repo"] = repo
            for i, g in enumerate(match.groups()):
                replacer_template["g"+str(i)] = g

            # And replace in it
            return Template(replace).substitute(replacer_template)

    # Read file and search
    file_content = read_file(file)
    new_file_content = file_content

    # Iterate over the regexes and replace
    for (m, r) in zip(match_regex, replace):
        new_file_content = re.sub(m, lambda x:replace_match(x, r), new_file_content)

    if file_content != new_file_content:
        std(file)
        # If something has changed, write back the file.
        write_file(file, new_file_content)
    if did:
        std(file)
    return did
Пример #28
0
def install_pack(pack):
    """Installs a single pack"""

    (pack, sep, pconfig) = pack.partition(":")

    pack_setup = get_pack_setup(pack)
    pack_dir = get_pack_dir(pack)

    if not pack_setup:
        return False

    # Create ext/ if it does not exist.
    if not os.path.isdir(lmh_locate("ext")):
        os.mkdir(lmh_locate("ext"))

    if pack_setup.is_installed(pack_dir):
        err("Pack", pack, "is already installed, use --update to update. ")
        return False

    try:
        return pack_setup.install(pack_dir, pconfig)
    except classes.UnsupportedAction:
        err("Pack", pack, "does not support installing. You may want to --update the pack?")
        return False
Пример #29
0
def export(f = None):
    """Exports the list of currently installed repositories. """

    # Get all locally installed directories
    installed = match_repos(lmh_locate("content"))

    if(f == None):
        for mod in installed:
            std(mod)
        return True
    try:
        write_file(f, os.linesep.join(installed))
        return True
    except:
        err("Unable to write %s" % f)
        return False
Пример #30
0
def export(f=None):
    """Exports the list of currently installed repositories. """

    # Get all locally installed directories
    installed = match_repos(lmh_locate("content"))

    if (f == None):
        for mod in installed:
            std(mod)
        return True
    try:
        write_file(f, os.linesep.join(installed))
        return True
    except:
        err("Unable to write %s" % f)
        return False
Пример #31
0
def do_install(rep):
    """
        Installs a single repository.
    """

    # pre-installation hook.
    std("Running pre-installation hook for '"+rep+"' ... ", newline=False)

    if not hook_pre_install(rep):
        err("Failed. ")
        return (False, [])
    std("Done. ")

    # Find the remote.
    std("Finding remote for '"+rep+"' ... ")
    repoURL = find_source(rep)

    # Did we find a url?
    if repoURL == False:
        std("")
        err("   Could not find a remote. ")
        return (False, [])

    std("   OK, will clone from '"+repoURL+"'")

    # Clone the repository.
    if not clone(lmh_locate("content"), repoURL, rep):
        err("git clone did not exit cleanly, cloning failed. ")
        err("""
Most likely your network connection is bad.
If you are using localmh_docker make sure that you have internet access inside the virtual machine.
""")
        return (False, [])

    std("   OK. ")

    # post-installation hook.
    std("Running post-installation hook for '"+rep+"' ... ", newline=False)

    if not hook_post_install(rep):
        err("Failed. ")
        return (False, [])
    std("Done. ")

    # Check for dependencies.
    return do_deps_install(rep)
Пример #32
0
def find_cached(files, match, replace = None, replace_match = None):
    """Finds and replaces inside of files. """

    # Make sure match and replace are arrays
    match = [match] if is_string(match) else match
    if replace != None:
        replace = [replace] if is_string(replace) else replace

        if len(replace) != len(match):
            err("Find and Replace patterns are not of the same length. ")
            return False


    rep = False
    for file in files:
        repo = os.path.relpath(find_repo_dir(file), lmh_locate("content"))
        matcher = [Template(m).substitute(repo=repo) for m in match]
        if replace != None:
            rep = find_and_replace_file(file, matcher, replace, replace_match = replace_match) or rep
        else:
            rep = find_file(file, matcher) or rep
    return rep
Пример #33
0
def do(args, unknown):
    # If there are no repositories, check everything for dependencies.
    if len(args.spec) == 0:
        std("Nothing to install, re-installing all existing repositories.  ")
        return install(*match_repos(lmh_locate("content")))

    if not get_config("install::noglobs"):
        args.spec = ls_remote(*args.spec)
        if len(args.spec) == 0:
            err("Nothing to install...")
            return True
        if args.no_confirm_install:
            std("Picked", len(args.spec),"repositories. ")
        else:
            std("Picked", len(args.spec),"repositories: ")
            std(*args.spec)
            if read_raw("Continue (y/N)?").lower() != "y":
                err("Installation aborted. ")
                return False


    return install(*args.spec)
Пример #34
0
def is_repo_dir(path, existence = True):
    """
        Checks if a directory contains a MathHub repository.

        Optimised to exit as soon as possible when the directory is not
        a repository.

        @param path {string} Path to check.
        @param existence {boolean} Do we do a theoretical test only or do we check for existence as well?

        @returns {boolean}
    """

    if re.match('^[^\/]+\/[^\/]+$', path):
        # it is already a name.
        name = path
    else:
        # it is not a name, so we need to find the relative_path.
        name = os.path.relpath(
            os.path.abspath(path),
            lmh_locate("content")
        )

        # if the name ends with a /, remove it.
        if name.endswith("/"):
            name = name[:-1]

        # if the path does not match, we need to exit.
        if not re.match('^[^\/]+\/[^\/]+$', name):
            return False

    # if we need existence, check it is a git directory
    if existence:
        return is_repo(path)

    # we have passed all the tests
    return True
Пример #35
0
from lmh.lib.packs import classes

from lmh.lib.dirs import lmh_locate
from lmh.lib.env import wget_executable
from lmh.lib.utils import mkdir_p
from lmh.lib.config import get_config

import subprocess
import os.path
import os
import stat
import sys

mmt_jar_dir = lmh_locate("ext", "MMT", "deploy")
mmt_jar_path = lmh_locate(mmt_jar_dir, "mmt.jar")


class MMTPack(classes.Pack):
    """The special MMT Pack"""
    def __init__(self, mmt_jar_source):
        self.mmt_jar_source = mmt_jar_source
        self.name = "MMT"
    def do_install(self, pack_dir, sstring):
        """Updates the MMT package"""
        return self.do_update(pack_dir,sstring)
    def do_update(self, pack_dir, sstring):
        """Install the MMT package"""

        # Make the directory
        mkdir_p(mmt_jar_dir)
        
Пример #36
0
def movemod(source, dest, modules, no_depcrawl, simulate = False):
    """Moves modules from source to dest. """

    # change directory to MathHub root, makes paths easier
    if simulate:
        std("cd "+lmh_locate("content"))
    else:
        os.chdir(lmh_locate("content"))

    finds = []
    replaces = []

    # Match the repos
    source = match_repo(source, root=lmh_locate("content"))
    dest = match_repo(dest, root=lmh_locate("content"))

    if source == None:
        err("Source repository does not exist, make sure it is installed. ")
        return False
    if dest == None:
        err("Destination repository does not exist, make sure it is installed. ")
        return False

    if source == dest:
        err("Cannot move modules when source and destination are the same. ")
        return False

    # Store original source and destination
    osource = source
    odest = dest

    # Make a list of all the moved files.
    moved_files = []

    local_finds = []
    local_replaces = []

    def run_lmh_find_moved(find, replace):
        if simulate:
            # We will run it over dest only.
            std("lmh", "find", json.dumps(find), "--replace", json.dumps(replace), "--apply", odest)
        else:
            # Append it to to a list.
            local_finds.append(find)
            local_replaces.append(replace)

    for module in modules:

        dest = odest

        # Figure out the full path to the source
        srcpath = source + "/source/" +  module

        # Assemble source paths further
        srcargs = (source + "/" + module).split("/")
        srcapath = "\\/".join(srcargs[:-1])
        srcbpath = srcargs[-1]

        # Assemble all the commands
        oldcall = "\[" + srcapath + "\]\{"+srcbpath+"\}"
        oldcall_long = "\[(.*)repos=" + srcapath + "(.*)\]\{"+srcbpath+"\}"
        oldcall_local = "\{"+srcbpath+ "\}"
        newcall = "[" + dest + "]{"+srcbpath+"}"
        newcall_long = "[$g1" + dest + "$g2]{"+srcbpath+"}"

        dest += "/source/"

        # Move the files
        if simulate:
            std("mv "+srcpath + ".*.tex"+ " "+ dest + " 2>/dev/null || true")
            std("mv "+srcpath + ".tex"+ " "+ dest + " 2>/dev/null || true")
        else:
            try:
                shutil.move(srcpath + ".tex", dest)
                moved_files.append(os.path.join(dest, os.path.basename(srcpath + ".tex")))
            except:
                pass

            for pat in glob.glob(srcpath + ".*.tex"):
                # try to move the file if it exists
                try:
                    shutil.move(pat, dest)
                    moved_files.append(os.path.join(dest, os.path.basename(pat)))
                except:
                    pass


        def run_lmh_find(find, replace):
            finds.append(find)
            replaces.append(replace)

        # Run all the commands
        m = "("+"|".join(["gimport", "guse", "gadopt"])+")"
        run_lmh_find(r'\\'+m+oldcall, '\\$g0'+newcall)
        run_lmh_find(r'\\'+m+oldcall_local, '\\$g0'+newcall)

        m = "("+ "|".join(["importmhmodule", "usemhmodule", "adoptmhmodule", "usemhvocab"]) + ")"
        run_lmh_find(r'\\'+m+oldcall_long, '\\$g0'+newcall_long)
        run_lmh_find(r'\\'+m+oldcall_local, '\\$g0'+newcall_long)

        # For the moved files, repalce gimport, guse, gadpot
        run_lmh_find_moved(r"\\("+"|".join(["gimport", "guse", "gadopt"])+")\["+dest[-len("/source/")]+"\]\{(.*)\}", "\\$g1{$g2}")

    # Update the moved files.
    run_lmh_find_moved(r"\\("+"|".join(["gimport", "guse", "gadopt"])+")\{(((?!(?<=\{)("+"|".join(modules)+")\}).)*?)\}", "\\$g1{$g2}")

    # Make the repo paths absolute
    osource = match_repo(osource, abs=True)
    odest = match_repo(odest, abs=True)

    files = reduce([find_files(r, "tex")[0] for r in match_repos(lmh_locate("content"), abs=True)])

    if simulate:
        for (f, r) in zip(finds, replaces):
            std("lmh find", json.dumps(f), "--replace", json.dumps(r), "--apply")

        if not no_depcrawl:
            calc_deps(False, dirname=osource)
            calc_deps(False, dirname=odest)

        return True

    else:
        std("updating paths in the following files: ")

        res1 = find_cached(files, finds, replace=replaces)
        res2 = find_cached(moved_files, local_finds, replace=local_replaces)

        if not no_depcrawl:
            res3 = calc_deps(True, osource)
            res4 = calc_deps(True, odest)
        else:
            res3 = True
            res4 = True

        return res1 and res2 and res3 and res4
Пример #37
0
def get_pack_dir(pack):
    return lmh_locate("ext", pack)
Пример #38
0
import json
import os
import os.path

from lmh.lib.io import std, err, read_file
from lmh.lib.dirs import lmh_locate
from lmh.lib.packs import classes

#
# Package Lookers
#
"""All available packs"""
av_packs = json.loads(read_file(lmh_locate("lib", "data", "packs.json")))

# Generate the all group, which is everything except for self.
av_packs["groups"]["all"] = list(av_packs["packs"].keys())
av_packs["groups"]["all"].remove("self")

#
# Resolve the specification for a certain pack
#


def resolve_package_spec(packages):
    """Resolves package specification. """

    to_install = set()
    for p in packages:
        (pname, sep, pconfig) = p.partition(":")
        if pname in av_packs["packs"]:
            to_install.add(p)
Пример #39
0
def find_repo_dir(path, existence=True):
    """
        Returns the absolute path to the repository contained in PATH or False.

        If you need to only check if you are in a repository, use is_in_repo
        instead.

        @param {string} path - Path to check
        @param {boolean} [existence = True] - Do we need to check for existence?

        @returns {string|boolean}
    """

    # we figure out the relative path
    namecheck = os.path.relpath(
        lmh_locate("content"),
        os.path.abspath(path),
    )

    # if we go into a directory, we

    if namecheck.startswith('../../'):
        path = lmh_locate("content", path)

    # find the relative path
    # by going relatively from the path to the data directory.
    name = os.path.relpath(os.path.abspath(path), lmh_locate("content"))

    # Check that the path does not leave the DATA directory.
    # This has to be the first component of the path
    # or the entire path.
    if name.startswith("../") or name == "..":
        return False

    # the repository name should be everything until the second slash
    # so go through the path and find it
    num_slash_correct = False
    abs_name = lmh_locate("content", "")
    for (i, c) in enumerate(name):
        if c == "/":
            if num_slash_correct:
                # we have found the second slash
                # we want to check for existence now.
                if existence and not is_repo(abs_name):
                    return False

                # and then return the name.
                return abs_name
            else:
                # we have found the first slash
                num_slash_correct = True
        # add the caracter to the name
        abs_name += c

    # do we have the correct number of slashes?
    # if so, we can return the path.
    if num_slash_correct:
        # again, we might have to check for existence.
        if existence and not is_repo(abs_name):
            return False
        return abs_name
    else:
        return False
Пример #40
0
from lmh.lib.packs import classes

from lmh.lib.dirs import lmh_locate
from lmh.lib.env import wget_executable
from lmh.lib.utils import mkdir_p
from lmh.lib.config import get_config

import subprocess
import os.path
import os
import stat
import sys

mmt_jar_dir = lmh_locate("ext", "MMT", "deploy")
mmt_jar_path = lmh_locate(mmt_jar_dir, "mmt.jar")


class MMTPack(classes.Pack):
    """The special MMT Pack"""
    def __init__(self, mmt_jar_source):
        self.mmt_jar_source = mmt_jar_source
        self.name = "MMT"

    def do_install(self, pack_dir, sstring):
        """Updates the MMT package"""
        return self.do_update(pack_dir, sstring)

    def do_update(self, pack_dir, sstring):
        """Install the MMT package"""

        # Make the directory
Пример #41
0
def get_pack_dir(pack):
    return lmh_locate("ext", pack)
Пример #42
0
def create(reponame, type="none", remote = True):
    """Creates a new repository in the given directory"""

    # Resolve the repository to create
    repo = match_repo(reponame, existence=False)
    if repo == None:
        err("Can not resolve repository to create. ")
        return False

    # Remote creation currently disabled
    if remote:
        err("Remote cration currently disabled. ")
        remote = False

    # and the full path
    absrepo = match_repo(reponame, abs=True, existence=False)

    repo_group = repo.split("/")[0]
    repo_name = repo.split("/")[1]

    # Check if it is already installed.
    # TODO: Use the other is_installed
    if is_installed(repo):
        err("Repository", repo, "already installed. ")
        err("Do you maybe want to push this to the remote?")
        return False

    # Make the directory if it does not yet exist.
    try:
        mkdir_p(absrepo)
    except:
        err("Can not create repository directory")
        return False

    if not get_config("init::allow_nonempty"):
        if not (not os.listdir(absrepo)):
            err("Target Directory is non-empty. ")
            err("If you want to enable lmh init on non-empty directories, please run")
            err("    lmh config init::allow_nonempty true")
            return False

    # Template Variables.
    tpl_vars = {
            "repo": repo,
            "repo_group": repo_group,
            "repo_name": repo_name,
            "install_dir": lmh_locate()
    }

    # Copy the base template
    if not copy_template_dir(os.path.join(emptyrepo_dir, "none"), absrepo, tpl_vars):
        err("Unable to create repository base. ")
        return False

    # Copy the specific type.
    if type != "none":
        type_dir = os.path.join(emptyrepo_dir, type)
        if os.path.isdir(type_dir):
            if not copy_template_dir(type_dir, absrepo, tpl_vars):
                err("Unable to use repository template. ")
                return False
        else:
            err("Unknown repository type: ", type)
            return False

    if git_root(absrepo) != absrepo:
        # Now lets make an init
        if not git_do(absrepo, "init"):
            err("Error creating git repository. ")
            err("The directory has been created successfully, however git init failed. ")
            err("Please run it manually. ")
            return False

    # Create the initial commit.
    if not (git_do(absrepo, "add", "-A") and git_commit(absrepo, "-m", "Repository created by lmh")):
        err("Error creating inital commit. ")
        err("The directory has been created successfully, however git commit failed. ")
        err("Please run it manually. ")
        return False

    # Can we find a remote for this?
    source = find_source(repo, quiet=True)

    # Don't do anything remote => we are done.
    if not remote:
        if source:
            if not git_do(absrepo, "remote", "add", "origin", source):
                err("Can not add origin. ")
                err("git is suddenly weird. ")
                return False
        else:
            std("Skipping remote creation because --no-remote is given. ")
        std("Repository created successfully. ")
        return True

    # Source does not exist => we will have to create it.
    if not source:
        source = create_remote(repo_group, repo_name)
        if not source:
            err("local repository created but remote creation failed. ")
            return False

    # Add the origin.
    if not git_do(absrepo, "remote", "add", "origin", source):
        err("Can not add origin. ")
        err("git is suddenly weird. ")
        return False

    if not git_push(absrepo, "-u", "origin", "master"):
        err("Repository created but could not push created repository. ")
        err("Check your network connection and try again using git push. ")
        return False

    std("Created new repository successfully. ")

    return True
Пример #43
0
"""
Configuration functions for lmh
"""

# TODO: Prefer the file in the home directory.
# If it does not exist, create it.
# If it does exist, migrate automatically.
# This will make sure that each user has their own configuration.

import json

from lmh.lib.dirs import lmh_locate
from lmh.lib.io import std, err, read_file, write_file, term_colors
"""Available configuration values. """
config_meta = json.loads(read_file(lmh_locate("lib", "data", "config.json")))
"""The configuration file for lmh"""
config_file = lmh_locate(
    "bin", "lmh.cfg")  # TODO: Store this in the home direcory instead
# will allow multiple users to read it.


def get_config(key):
    """
    Gets a given configuration setting. If it does not exist in the 
    configuration file, the default will be returned
    """

    # check if the given key exists in the configuration
    if not key in config_meta:
        err("Option", key, "does not exist. ")
        raise KeyError
Пример #44
0
def locate_compile_target(path, try_root=True):
    """
        Finds all targets to be compiled. (Files AND Folders inside source/)
        @param path Path to find files in
    """
    spec = path

    # if we are not inside the data directory, return.
    if path.startswith(os.path.abspath(lmh_locate())) and not path.startswith(
            os.path.abspath(lmh_locate("content"))):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)
        return []

    # If we are inside the root, go inside the folder.
    relpath = os.path.relpath(lmh_locate("content"), os.path.realpath(path))
    if relpath == "../..":
        path = path + "/source"
    elif not relpath.endswith("../.."):
        return reduce([(locate_compile_target(p))
                       for p in find_repo_subdirs(path)])
    # Get the absolute path.
    path = os.path.realpath(path)

    # If it does not exist, return.
    if not os.path.isfile(path) and not os.path.isdir(path):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Could not find anything matching ", "'" + spec + "'")
        return []

    # find the repository dir.
    repo_dir = find_repo_dir(path, existence=True)
    repo_name = os.path.relpath(repo_dir, lmh_locate("content"))
    if repo_dir == False:
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Matching item to ", "'" + spec + "'",
            "are outside of repository. ")
        return []

    # Find the source directory and get a relative path
    repos_src_dir = os.path.join(repo_dir, "source")
    path = os.path.relpath(path, repos_src_dir)

    # if we need to go up, we are not in source
    if path.startswith("../"):
        # if we have not tried the root, we should try again.
        if try_root:
            return locate_compile_target(lmh_locate("content", spec), False)

        err("Matching item to", "'" + spec + "'",
            "are outside of the source directory. ")
        return []

    # return the name of the repository and the path inside the repository.
    return [(repo_name, path)]
Пример #45
0
 def do_update(self, pack_dir, update):
     return pull(lmh_locate())
Пример #46
0
def match_repos(repos, root=os.getcwd(), abs=False):
    """
        Matches a list of specefiers to repositories.

        @param {string[]} repos - Specefiers to match
        @param {string} root - Root directory to use
        @param {boolean} [abs=False] - Should absolute paths be returned?

        @returns string[] - repository paths
    """

    # For each element do the following:
    # 1) Check if given directory exists relatively from current root.
    #       1a) If it is a repository or repository subdir, return that
    #        1b) If it is inside the data_dir, return all repo subdirectories
    # 2) If it does not exist, resolve it as glob.glob from install_dir
    # 3) For each of the found directories, run 1)

    # If the repositories are just a string, we want an array.
    if is_string(repos):
        repos = [repos]
    # it is already an array, so remove doubles please.
    else:
        repos = remove_doubles(repos)

    # the glob expressions we want to use
    # and the repo directories we will use.
    results = set()

    def match_repo_name(r):

        # make an absolute path
        # this will also work with globs
        names = os.path.abspath(os.path.join(root, r))

        # it is not inside the data directory
        # so try again next time
        if not is_in_data(names):
            return True

        # find the relative path of it to the root.
        names = os.path.relpath(
            os.path.abspath(names),
            lmh_locate("content")
        )

        # make sure everything ends with a slash
        # so that we can count properly
        if names[-1] != "/":
            names += "/"

        # Now figure out which level we are at
        # by counting slashes
        num_slashes = 0
        for c in names:
            # count the slashes
            # by increasing the level.
            if c == "/":
                num_slashes += 1


        # if we have no slashes
        # we are toplevel
        # and can pretty much exit everything
        if names == "./":
            names = lmh_locate("content", "*", "*")

        # if we have 1 slash
        # we are one level deep
        elif num_slashes == 1:
            names = lmh_locate("content", names, "*")
        else:
            names = lmh_locate("content", names)

        # now expand with the help of globs
        names = glob.glob(names)

        # and check if they exist
        names = list(filter(is_repo, names))

        # if we found something
        # we should through the item
        if len(names) > 0:
            results.update(names)
            return False
        else:
            return True

    # now filter the repos
    repos = list(filter(match_repo_name, repos))

    # repeat again with data_dir as root
    root = lmh_locate("content")
    repos = list(filter(match_repo_name, repos))


    # if we want the relative paths we need to set them properly.
    if not abs:
        return [os.path.relpath(d, lmh_locate("content")) for d in results]

    return list(results)
Пример #47
0
def find_repo_dir(path, existence=True):
    """
        Returns the absolute path to the repository contained in PATH or False.

        If you need to only check if you are in a repository, use is_in_repo
        instead.

        @param {string} path - Path to check
        @param {boolean} [existence = True] - Do we need to check for existence?

        @returns {string|boolean}
    """

    # we figure out the relative path
    namecheck = os.path.relpath(
        lmh_locate("content"),
        os.path.abspath(path),
    )

    # if we go into a directory, we

    if namecheck.startswith('../../'):
        path = lmh_locate("content", path)

    # find the relative path
    # by going relatively from the path to the data directory.
    name = os.path.relpath(
        os.path.abspath(path),
        lmh_locate("content")
    )



    # Check that the path does not leave the DATA directory.
    # This has to be the first component of the path
    # or the entire path.
    if name.startswith("../") or name == "..":
        return False

    # the repository name should be everything until the second slash
    # so go through the path and find it
    num_slash_correct = False
    abs_name = lmh_locate("content", "")
    for (i, c) in enumerate(name):
        if c == "/":
            if num_slash_correct:
                # we have found the second slash
                # we want to check for existence now.
                if existence and not is_repo(abs_name):
                    return False

                # and then return the name.
                return abs_name
            else:
                # we have found the first slash
                num_slash_correct = True
        # add the caracter to the name
        abs_name += c

    # do we have the correct number of slashes?
    # if so, we can return the path.
    if num_slash_correct:
        # again, we might have to check for existence.
        if existence and not is_repo(abs_name):
            return False
        return abs_name
    else:
        return False
Пример #48
0
 def do_update(self, pack_dir, update):
     return pull(lmh_locate())
Пример #49
0
def version():
    """
    Returns the current version of lmh
    """
    return read_file(lmh_locate("lib", "data", "version"))
Пример #50
0
def match_repos(repos, root=os.getcwd(), abs=False):
    """
        Matches a list of specefiers to repositories.

        @param {string[]} repos - Specefiers to match
        @param {string} root - Root directory to use
        @param {boolean} [abs=False] - Should absolute paths be returned?

        @returns string[] - repository paths
    """

    # For each element do the following:
    # 1) Check if given directory exists relatively from current root.
    #       1a) If it is a repository or repository subdir, return that
    #        1b) If it is inside the data_dir, return all repo subdirectories
    # 2) If it does not exist, resolve it as glob.glob from install_dir
    # 3) For each of the found directories, run 1)

    # If the repositories are just a string, we want an array.
    if is_string(repos):
        repos = [repos]
    # it is already an array, so remove doubles please.
    else:
        repos = remove_doubles(repos)

    # the glob expressions we want to use
    # and the repo directories we will use.
    results = set()

    def match_repo_name(r):

        # make an absolute path
        # this will also work with globs
        names = os.path.abspath(os.path.join(root, r))

        # it is not inside the data directory
        # so try again next time
        if not is_in_data(names):
            return True

        # find the relative path of it to the root.
        names = os.path.relpath(os.path.abspath(names), lmh_locate("content"))

        # make sure everything ends with a slash
        # so that we can count properly
        if names[-1] != "/":
            names += "/"

        # Now figure out which level we are at
        # by counting slashes
        num_slashes = 0
        for c in names:
            # count the slashes
            # by increasing the level.
            if c == "/":
                num_slashes += 1

        # if we have no slashes
        # we are toplevel
        # and can pretty much exit everything
        if names == "./":
            names = lmh_locate("content", "*", "*")

        # if we have 1 slash
        # we are one level deep
        elif num_slashes == 1:
            names = lmh_locate("content", names, "*")
        else:
            names = lmh_locate("content", names)

        # now expand with the help of globs
        names = glob.glob(names)

        # and check if they exist
        names = list(filter(is_repo, names))

        # if we found something
        # we should through the item
        if len(names) > 0:
            results.update(names)
            return False
        else:
            return True

    # now filter the repos
    repos = list(filter(match_repo_name, repos))

    # repeat again with data_dir as root
    root = lmh_locate("content")
    repos = list(filter(match_repo_name, repos))

    # if we want the relative paths we need to set them properly.
    if not abs:
        return [os.path.relpath(d, lmh_locate("content")) for d in results]

    return list(results)
Пример #51
0
def version():
    """
    Returns the current version of lmh
    """
    return read_file(lmh_locate("lib", "data", "version"))
Пример #52
0
def do(args, unknown):
    std(lmh_locate())
    return True
Пример #53
0
def find_repo_subdirs(path):
    """
        Returns the absolute path to the all repositories contained in PATH.

        @param {string} path - Path to check

        @returns {string[]}
    """

    # path needs to be a directory
    if not os.path.isdir(path):
        return []

    # We are not inside the data directory
    # so we need to return nothing
    if not is_in_data(path):
        return []

    # If we can find the current repository path
    # we can return it.
    repo_path = find_repo_dir(path)
    if repo_path:
        return [repo_path]

    # Find the relative path from the root to the current directory
    name = os.path.relpath(
        os.path.abspath(path),
        lmh_locate("content")
    )

    # make sure everything ends with a slash
    # so that we can count properly
    if name[-1] != "/":
        name += "/"

    # Now figure out which level we are at
    # by counting slashes
    num_slashes = 0
    for c in name:
        # count the slashes
        # by increasing the level.
        if c == "/":
            num_slashes += 1


    # if we have no slashes
    # we are toplevel
    if name == "./":
        name = lmh_locate("content", "*", "*")
    # if we have 1 slash
    # we are one level deep
    elif num_slashes == 1:
        name = lmh_locate("content", name, "*")
    # else something is wrong
    # and we are nowhere
    else:
        return []

    # now we can match the paths via glob.glob
    # and check that they exist
    return list(filter(is_repo, glob.glob(name)))
Пример #54
0
import json
import os
import os.path

from lmh.lib.io import std, err, read_file
from lmh.lib.dirs import lmh_locate
from lmh.lib.packs import classes


#
# Package Lookers
#

"""All available packs"""
av_packs = json.loads(read_file(lmh_locate("lib", "data", "packs.json")))

# Generate the all group, which is everything except for self.
av_packs["groups"]["all"] = list(av_packs["packs"].keys())
av_packs["groups"]["all"].remove("self")

#
# Resolve the specification for a certain pack
#

def resolve_package_spec(packages):
    """Resolves package specification. """

    to_install = set()
    for p in packages:
        (pname, sep, pconfig) = p.partition(":")
        if pname in av_packs["packs"]:
Пример #55
0
from lmh.lib.io import is_string
from lmh.lib.io import std, err, read_file
from lmh.lib.dirs import lmh_locate
from lmh.lib.config import get_config

from subprocess import Popen

import shlex

try:
    import signal
except:
    pass
"""sty directory"""
stydir = lmh_locate("sty")
"""sTex directory"""
stexstydir = lmh_locate("ext", "sTeX", "sty")
"""LatexML directory"""
latexmlstydir = lmh_locate("ext", "LaTeXML", "lib", "LaTeXML", "texmf")


def which(program):
    """
    Returns the full path to a program that can be found in the users $PATH
    variable. Similar to the *nix command which (or the windows command where).
    """
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
Пример #56
0
"""
Configuration functions for lmh
"""

# TODO: Prefer the file in the home directory. 
# If it does not exist, create it. 
# If it does exist, migrate automatically. 
# This will make sure that each user has their own configuration. 

import json

from lmh.lib.dirs import lmh_locate
from lmh.lib.io import std, err, read_file, write_file, term_colors

"""Available configuration values. """
config_meta = json.loads(read_file(lmh_locate("lib", "data", "config.json")))

"""The configuration file for lmh"""
config_file = lmh_locate("bin", "lmh.cfg") # TODO: Store this in the home direcory instead
                                            # will allow multiple users to read it. 

def get_config(key):
    """
    Gets a given configuration setting. If it does not exist in the 
    configuration file, the default will be returned
    """

    # check if the given key exists in the configuration
    if not key in config_meta:
        err("Option", key, "does not exist. ")
        raise KeyError
Пример #57
0
def movemod(source, dest, modules, no_depcrawl, simulate=False):
    """Moves modules from source to dest. """

    # change directory to MathHub root, makes paths easier
    if simulate:
        std("cd " + lmh_locate("content"))
    else:
        os.chdir(lmh_locate("content"))

    finds = []
    replaces = []

    # Match the repos
    source = match_repo(source, root=lmh_locate("content"))
    dest = match_repo(dest, root=lmh_locate("content"))

    if source == None:
        err("Source repository does not exist, make sure it is installed. ")
        return False
    if dest == None:
        err("Destination repository does not exist, make sure it is installed. "
            )
        return False

    if source == dest:
        err("Cannot move modules when source and destination are the same. ")
        return False

    # Store original source and destination
    osource = source
    odest = dest

    # Make a list of all the moved files.
    moved_files = []

    local_finds = []
    local_replaces = []

    def run_lmh_find_moved(find, replace):
        if simulate:
            # We will run it over dest only.
            std("lmh", "find", json.dumps(find), "--replace",
                json.dumps(replace), "--apply", odest)
        else:
            # Append it to to a list.
            local_finds.append(find)
            local_replaces.append(replace)

    for module in modules:

        dest = odest

        # Figure out the full path to the source
        srcpath = source + "/source/" + module

        # Assemble source paths further
        srcargs = (source + "/" + module).split("/")
        srcapath = "\\/".join(srcargs[:-1])
        srcbpath = srcargs[-1]

        # Assemble all the commands
        oldcall = "\[" + srcapath + "\]\{" + srcbpath + "\}"
        oldcall_long = "\[(.*)repos=" + srcapath + "(.*)\]\{" + srcbpath + "\}"
        oldcall_local = "\{" + srcbpath + "\}"
        newcall = "[" + dest + "]{" + srcbpath + "}"
        newcall_long = "[$g1" + dest + "$g2]{" + srcbpath + "}"

        dest += "/source/"

        # Move the files
        if simulate:
            std("mv " + srcpath + ".*.tex" + " " + dest +
                " 2>/dev/null || true")
            std("mv " + srcpath + ".tex" + " " + dest + " 2>/dev/null || true")
        else:
            try:
                shutil.move(srcpath + ".tex", dest)
                moved_files.append(
                    os.path.join(dest, os.path.basename(srcpath + ".tex")))
            except:
                pass

            for pat in glob.glob(srcpath + ".*.tex"):
                # try to move the file if it exists
                try:
                    shutil.move(pat, dest)
                    moved_files.append(
                        os.path.join(dest, os.path.basename(pat)))
                except:
                    pass

        def run_lmh_find(find, replace):
            finds.append(find)
            replaces.append(replace)

        # Run all the commands
        m = "(" + "|".join(["gimport", "guse", "gadopt"]) + ")"
        run_lmh_find(r'\\' + m + oldcall, '\\$g0' + newcall)
        run_lmh_find(r'\\' + m + oldcall_local, '\\$g0' + newcall)

        m = "(" + "|".join([
            "importmhmodule", "usemhmodule", "adoptmhmodule", "usemhvocab"
        ]) + ")"
        run_lmh_find(r'\\' + m + oldcall_long, '\\$g0' + newcall_long)
        run_lmh_find(r'\\' + m + oldcall_local, '\\$g0' + newcall_long)

        # For the moved files, repalce gimport, guse, gadpot
        run_lmh_find_moved(
            r"\\(" + "|".join(["gimport", "guse", "gadopt"]) + ")\[" +
            dest[-len("/source/")] + "\]\{(.*)\}", "\\$g1{$g2}")

    # Update the moved files.
    run_lmh_find_moved(
        r"\\(" + "|".join(["gimport", "guse", "gadopt"]) + ")\{(((?!(?<=\{)(" +
        "|".join(modules) + ")\}).)*?)\}", "\\$g1{$g2}")

    # Make the repo paths absolute
    osource = match_repo(osource, abs=True)
    odest = match_repo(odest, abs=True)

    files = reduce([
        find_files(r, "tex")[0]
        for r in match_repos(lmh_locate("content"), abs=True)
    ])

    if simulate:
        for (f, r) in zip(finds, replaces):
            std("lmh find", json.dumps(f), "--replace", json.dumps(r),
                "--apply")

        if not no_depcrawl:
            calc_deps(False, dirname=osource)
            calc_deps(False, dirname=odest)

        return True

    else:
        std("updating paths in the following files: ")

        res1 = find_cached(files, finds, replace=replaces)
        res2 = find_cached(moved_files, local_finds, replace=local_replaces)

        if not no_depcrawl:
            res3 = calc_deps(True, osource)
            res4 = calc_deps(True, odest)
        else:
            res3 = True
            res4 = True

        return res1 and res2 and res3 and res4