Пример #1
0
    def _configure(self):
        """ Parse configuration from git config """
        sc = StackedConfig(StackedConfig.default_backends())
        self.config = {}

        # Get top level directory of project
        proc = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        self.config['top_dir'] = proc.communicate()[0]

        if proc.returncode != 0:
            exit_code = 20
            log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
            sys.exit(exit_code)

        self.config['deploy_file'] = self.config['top_dir'] + '/.git'

        try:
            self.config['hook_dir'] = sc.get('deploy', 'hook-dir')
        except KeyError:
            exit_code = 21
            log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
            sys.exit(exit_code)

        try:
            self.config['repo_name'] = sc.get('deploy', 'tag-prefix')
        except KeyError:
            exit_code = 22
            log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
            sys.exit(exit_code)
        self.config['sync_dir'] = '{0}/sync'.format(self.config['hook_dir'])
Пример #2
0
    def create(self, title="tessera title goes here"):
        """ create a new tessera with title {title}.

            @returns Tessera object of the new Tessera
        """
        uuid = uuid1()
        tessera_path = os.path.join(Tessera._tesserae, str(uuid))
        tessera_file = "%s/tessera" % tessera_path
        os.mkdir(tessera_path)
        fin = open(os.path.join(Tessera._tesserae, "template"), "r")
        fout = open(tessera_file, "w")
        for line in fin.readlines():
            if line == "@title@\n":
                line = "# %s\n" % title
            fout.write(line)
        fin.close()
        fout.close()

        tessera_info = "%s/info" % tessera_path
        fout = open(tessera_info, "w")
        c = StackedConfig(StackedConfig.default_backends())
        fout.write("author: %s\n"%c.get("user", "name"))
        fout.write("email: %s\n"%c.get("user", "email"))
        fout.write("updated: %d\n"%int(time()))
        fout.close()

        return Tessera(tessera_path, self._config)
Пример #3
0
    def create(self, title="tessera title goes here"):
        """ create a new tessera with title {title}.

            @returns Tessera object of the new Tessera
        """
        uuid = uuid1()
        tessera_path = os.path.join(Tessera._tesserae, str(uuid))
        tessera_file = "%s/tessera" % tessera_path
        os.mkdir(tessera_path)
        fin = open(os.path.join(Tessera._tesserae, "template"), "r")
        fout = open(tessera_file, "w")
        for line in fin.readlines():
            if line == "@title@\n":
                line = "# %s\n" % title
            fout.write(line)
        fin.close()
        fout.close()

        tessera_info = "%s/info" % tessera_path
        fout = open(tessera_info, "w")
        c = StackedConfig(StackedConfig.default_backends())
        fout.write("author: %s\n" % c.get("user", "name"))
        fout.write("email: %s\n" % c.get("user", "email"))
        fout.write("updated: %d\n" % int(time()))
        fout.close()

        return Tessera(tessera_path, self._config)
Пример #4
0
 def get_config_stack(self):
     from dulwich.config import StackedConfig
     backends = []
     p = self.get_config()
     if p is not None:
         backends.append(p)
         writable = p
     else:
         writable = None
     backends.extend(StackedConfig.default_backends())
     return StackedConfig(backends, writable=writable)
Пример #5
0
    def get_config_stack(self):
        """Return a config stack for this repository.

        This stack accesses the configuration for both this repository
        itself (.git/config) and the global configuration, which usually
        lives in ~/.gitconfig.

        :return: `Config` instance for this repository
        """
        from dulwich.config import StackedConfig
        backends = [self.get_config()] + StackedConfig.default_backends()
        return StackedConfig(backends, writable=backends[0])
Пример #6
0
def configure(**kwargs):
    """ Parse configuration from git config """
    sc = StackedConfig(StackedConfig.default_backends())
    config = {}

    # Get top level directory of project
    proc = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE)
    config['top_dir'] = proc.communicate()[0].strip()

    if proc.returncode != 0:
        exit_code = 20
        log.error("{0} :: {1}".format(__name__, exit_codes[exit_code]))
        sys.exit(exit_code)

    config['deploy_file'] = config['top_dir'] + '/.git/.deploy'

    # Define the key names, git config names, and error codes
    config_elements = {
        'hook_dir': ('deploy', 'hook-dir', 21),
        'path': ('deploy', 'path', 23),
        'user': ('deploy', 'user', 24),
        'target': ('deploy', 'target', 25),
        'repo_name': ('deploy', 'tag-prefix', 22),
        'remote': ('deploy', 'remote', 26),
        'branch': ('deploy', 'branch', 27),
        'client_path': ('deploy', 'client-path', 19),
        'user.name': ('user', 'name', 28),
        'user.email': ('user', 'email', 29),
        'deploy.key_path': ('deploy', 'key-path', 37),
        'deploy.test_repo': ('deploy', 'test-repo-path', 38),
    }

    # Assign the values of each git config element
    for key, value in config_elements.iteritems():
        try:
            # Override with kwargs if the attribute exists
            if key in kwargs:
                config[key] = kwargs[key]
            else:
                config[key] = sc.get(value[0], value[1])
        except KeyError:
            exit_code = value[2]
            log.error("{0} :: {1}".format(__name__, exit_codes[exit_code]))
            sys.exit(exit_code)

    config['sync_dir'] = '{0}/sync'.format(config['hook_dir'])

    return config
 def sync(self, no_deps=False, force=False):
     """
         * add a sync tag
         * write a .deploy file with the tag information
         * call a sync hook with the prefix (repo) and tag info
     """
     # TODO: do git calls in dulwich, rather than shelling out
     # TODO: get all configuration via a function, and get it during main
     if "lock" not in os.listdir(".git/deploy"):
         exit_code = 20
         log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
         return exit_code
     sc = StackedConfig(StackedConfig.default_backends())
     try:
         hook_dir = sc.get("deploy", "hook-dir")
     except KeyError:
         exit_code = 21
         log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
         return exit_code
     try:
         repo_name = sc.get("deploy", "tag-prefix")
     except KeyError:
         exit_code = 22
         log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
         return exit_code
     sync_dir = "{0}/sync".format(hook_dir)
     sync_script = "{0}/{1}.sync".format(sync_dir, repo_name)
     _tag = "{0}-sync-{1}".format(repo_name, datetime.now().strftime(DATE_TIME_TAG_FORMAT))
     proc = subprocess.Popen(["/usr/bin/git tag", "-a", _tag])
     if proc.returncode != 0:
         exit_code = 23
         log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
         return exit_code
     # TODO: use a pluggable sync system rather than shelling out
     if os.path.exists(sync_script):
         proc = subprocess.Popen(
             [
                 sync_script,
                 '--repo="{0}"'.format(repo_name),
                 '--tag="{0}"'.format(_tag),
                 '--force="{0}"'.format(force),
             ]
         )
         log.info(proc.stdout.read())
         if proc.returncode != 0:
             exit_code = 24
             log.error("{0}::{1}".format(__name__, exit_codes[exit_code]))
             return exit_code
Пример #8
0
def ls_remote(remote):
    """List the refs in a remote.

    :param remote: Remote repository location
    :return: Dictionary with remote refs
    """
    config = StackedConfig.default()
    client, host_path = get_transport_and_path(remote, config=config)
    return client.get_refs(host_path)
Пример #9
0
def ls_remote(remote, config=None, **kwargs):
    """List the refs in a remote.

    :param remote: Remote repository location
    :param config: Configuration to use
    :return: Dictionary with remote refs
    """
    if config is None:
        config = StackedConfig.default()
    client, host_path = get_transport_and_path(remote, config=config, **kwargs)
    return client.get_refs(host_path)
Пример #10
0
def ls_remote(remote, config=None, **kwargs):
    """List the refs in a remote.

    :param remote: Remote repository location
    :param config: Configuration to use
    :return: Dictionary with remote refs
    """
    if config is None:
        config = StackedConfig.default()
    client, host_path = get_transport_and_path(remote, config=config, **kwargs)
    return client.get_refs(host_path)
Пример #11
0
    def get_config_stack(self):
        """Return a config stack for this repository.

        This stack accesses the configuration for both this repository
        itself (.git/config) and the global configuration, which usually
        lives in ~/.gitconfig.

        :return: `Config` instance for this repository
        """
        from dulwich.config import StackedConfig
        backends = [self.get_config()] + StackedConfig.default_backends()
        return StackedConfig(backends, writable=backends[0])
Пример #12
0
    def create(cls, basepath, title):
        t_id = str(generate_uniq_id())
        t_path = os.path.join(basepath, t_id)
        t_file = os.path.join(t_path, Tessera.TESSERA_FILENAME)
        t_info = os.path.join(t_path, Tessera.INFO_FILENAME)

        os.makedirs(t_path)

        with open(Tessera.NEW_TESSERA_TEMPLATE, "r") as fin:
            with open(t_file, "w+") as fout:
                for l in fin.readlines():
                    if l == "@title@\n":
                        l = "# %s\n" % title
                    fout.write(l)

        with open(t_info, "w+") as f:
            c = StackedConfig(StackedConfig.default_backends())
            f.write("author: %s\n" % c.get("user", "name"))
            f.write("email: %s\n" % c.get("user", "email"))
            f.write("updated: %s\n" % datetime.now().strftime("%Y-%m-%dT%H:%M:%S"))

        t = Tessera(t_id, t_path)
        return t
Пример #13
0
 def test_default_backends(self):
     StackedConfig.default_backends()
Пример #14
0
 def test_default_backends(self):
     self.makeSafeEnv()
     StackedConfig.default_backends()
Пример #15
0
 def test_default_backends(self):
     self.makeSafeEnv()
     StackedConfig.default_backends()
Пример #16
0
def clone(source,
          target=None,
          bare=False,
          checkout=None,
          errstream=default_bytes_err_stream,
          outstream=None,
          origin=b"origin",
          **kwargs):
    """Clone a local or remote git repository.

    :param source: Path or URL for source repository
    :param target: Path to target repository (optional)
    :param bare: Whether or not to create a bare repository
    :param checkout: Whether or not to check-out HEAD after cloning
    :param errstream: Optional stream to write progress to
    :param outstream: Optional stream to write progress to (deprecated)
    :param origin: Name of remote from the repository used to clone
    :return: The new repository
    """
    # TODO(jelmer): This code overlaps quite a bit with Repo.clone
    if outstream is not None:
        import warnings
        warnings.warn(
            "outstream= has been deprecated in favour of errstream=.",
            DeprecationWarning,
            stacklevel=3)
        errstream = outstream

    if checkout is None:
        checkout = (not bare)
    if checkout and bare:
        raise ValueError("checkout and bare are incompatible")

    config = StackedConfig.default()
    client, host_path = get_transport_and_path(source, config=config, **kwargs)

    if target is None:
        target = host_path.split("/")[-1]

    if not os.path.exists(target):
        os.mkdir(target)

    if bare:
        r = Repo.init_bare(target)
    else:
        r = Repo.init(target)

    reflog_message = b'clone: from ' + source.encode('utf-8')
    try:
        fetch_result = fetch(r, host_path, origin, message=reflog_message)
        target_config = r.get_config()
        if not isinstance(source, bytes):
            source = source.encode(DEFAULT_ENCODING)
        target_config.set((b'remote', origin), b'url', source)
        target_config.set((b'remote', origin), b'fetch',
                          b'+refs/heads/*:refs/remotes/' + origin + b'/*')
        target_config.write_to_path()
        # TODO(jelmer): Support symref capability,
        # https://github.com/jelmer/dulwich/issues/485
        try:
            head = r[fetch_result[b'HEAD']]
        except KeyError:
            head = None
        else:
            r[b'HEAD'] = head.id
        if checkout and not bare and head is not None:
            errstream.write(b'Checking out ' + head.id + b'\n')
            r.reset_index(head.tree)
    except BaseException:
        r.close()
        raise

    return r
Пример #17
0
 def test_default_backends(self):
     StackedConfig.default_backends()
Пример #18
0
def clone(source, target=None, bare=False, checkout=None,
          errstream=default_bytes_err_stream, outstream=None,
          origin=b"origin", **kwargs):
    """Clone a local or remote git repository.

    :param source: Path or URL for source repository
    :param target: Path to target repository (optional)
    :param bare: Whether or not to create a bare repository
    :param checkout: Whether or not to check-out HEAD after cloning
    :param errstream: Optional stream to write progress to
    :param outstream: Optional stream to write progress to (deprecated)
    :param origin: Name of remote from the repository used to clone
    :return: The new repository
    """
    # TODO(jelmer): This code overlaps quite a bit with Repo.clone
    if outstream is not None:
        import warnings
        warnings.warn(
            "outstream= has been deprecated in favour of errstream=.",
            DeprecationWarning, stacklevel=3)
        errstream = outstream

    if checkout is None:
        checkout = (not bare)
    if checkout and bare:
        raise ValueError("checkout and bare are incompatible")

    config = StackedConfig.default()
    client, host_path = get_transport_and_path(source, config=config, **kwargs)

    if target is None:
        target = host_path.split("/")[-1]

    if not os.path.exists(target):
        os.mkdir(target)

    if bare:
        r = Repo.init_bare(target)
    else:
        r = Repo.init(target)

    reflog_message = b'clone: from ' + source.encode('utf-8')
    try:
        fetch_result = fetch(r, host_path, origin, message=reflog_message)
        target_config = r.get_config()
        if not isinstance(source, bytes):
            source = source.encode(DEFAULT_ENCODING)
        target_config.set((b'remote', origin), b'url', source)
        target_config.set(
            (b'remote', origin), b'fetch',
            b'+refs/heads/*:refs/remotes/' + origin + b'/*')
        target_config.write_to_path()
        # TODO(jelmer): Support symref capability,
        # https://github.com/jelmer/dulwich/issues/485
        try:
            head = r[fetch_result[b'HEAD']]
        except KeyError:
            head = None
        else:
            r[b'HEAD'] = head.id
        if checkout and not bare and head is not None:
            errstream.write(b'Checking out ' + head.id + b'\n')
            r.reset_index(head.tree)
    except BaseException:
        r.close()
        raise

    return r
Пример #19
0
def clone(source,
          target=None,
          bare=False,
          checkout=None,
          errstream=default_bytes_err_stream,
          outstream=None,
          origin=b"origin"):
    """Clone a local or remote git repository.

    :param source: Path or URL for source repository
    :param target: Path to target repository (optional)
    :param bare: Whether or not to create a bare repository
    :param checkout: Whether or not to check-out HEAD after cloning
    :param errstream: Optional stream to write progress to
    :param outstream: Optional stream to write progress to (deprecated)
    :param origin: Name of remote from the repository used to clone
    :return: The new repository
    """
    if outstream is not None:
        import warnings
        warnings.warn(
            "outstream= has been deprecated in favour of errstream=.",
            DeprecationWarning,
            stacklevel=3)
        errstream = outstream

    if checkout is None:
        checkout = (not bare)
    if checkout and bare:
        raise ValueError("checkout and bare are incompatible")

    config = StackedConfig.default()
    client, host_path = get_transport_and_path(source, config=config)

    if target is None:
        target = host_path.split("/")[-1]

    if not os.path.exists(target):
        os.mkdir(target)

    if bare:
        r = Repo.init_bare(target)
    else:
        r = Repo.init(target)
    try:
        remote_refs = client.fetch(
            host_path,
            r,
            determine_wants=r.object_store.determine_wants_all,
            progress=errstream.write)
        r.refs.import_refs(
            b'refs/remotes/' + origin, {
                n[len(b'refs/heads/'):]: v
                for (n, v) in remote_refs.items()
                if n.startswith(b'refs/heads/')
            })
        r.refs.import_refs(
            b'refs/tags', {
                n[len(b'refs/tags/'):]: v
                for (n, v) in remote_refs.items()
                if n.startswith(b'refs/tags/')
                and not n.endswith(ANNOTATED_TAG_SUFFIX)
            })
        target_config = r.get_config()
        if not isinstance(source, bytes):
            source = source.encode(DEFAULT_ENCODING)
        target_config.set((b'remote', origin), b'url', source)
        target_config.set((b'remote', origin), b'fetch',
                          b'+refs/heads/*:refs/remotes/' + origin + b'/*')
        target_config.write_to_path()
        if checkout and not bare:
            # TODO(jelmer): Support symref capability,
            # https://github.com/jelmer/dulwich/issues/485
            try:
                head = r[remote_refs[b"HEAD"]]
            except KeyError:
                pass
            else:
                r[b'HEAD'] = head.id
                errstream.write(b'Checking out ' + head.id + b'\n')
                r.reset_index(head.tree)
    except BaseException:
        r.close()
        raise

    return r
Пример #20
0
 def test_default_backends(self):
     self.addCleanup(os.environ.__setitem__, "HOME", os.environ["HOME"])
     os.environ["HOME"] = "/nonexistant"
     StackedConfig.default_backends()