Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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)))
Exemplo n.º 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
Exemplo n.º 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 []
Exemplo n.º 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)
Exemplo n.º 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 []
Exemplo n.º 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))
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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)]
Exemplo n.º 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
Exemplo n.º 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))
Exemplo n.º 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))
Exemplo n.º 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"))
Exemplo n.º 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"))
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 35
0
Arquivo: MMT.py Projeto: KWARC/localmh
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)
        
Exemplo n.º 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
Exemplo n.º 37
0
def get_pack_dir(pack):
    return lmh_locate("ext", pack)
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 41
0
def get_pack_dir(pack):
    return lmh_locate("ext", pack)
Exemplo n.º 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
Exemplo n.º 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
Exemplo n.º 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)]
Exemplo n.º 45
0
 def do_update(self, pack_dir, update):
     return pull(lmh_locate())
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 48
0
 def do_update(self, pack_dir, update):
     return pull(lmh_locate())
Exemplo n.º 49
0
def version():
    """
    Returns the current version of lmh
    """
    return read_file(lmh_locate("lib", "data", "version"))
Exemplo n.º 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)
Exemplo n.º 51
0
def version():
    """
    Returns the current version of lmh
    """
    return read_file(lmh_locate("lib", "data", "version"))
Exemplo n.º 52
0
def do(args, unknown):
    std(lmh_locate())
    return True
Exemplo n.º 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)))
Exemplo n.º 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"]:
Exemplo n.º 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)
Exemplo n.º 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
Exemplo n.º 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