def main():

    parser = make_parser()
    args = parser.parse_args()

    pathf.check_technical_area(args.area, args.module_name)

    module = args.module_name
    source = pathf.dev_module_path(module, args.area)
    logging.debug(source)

    if vcs_git.is_server_repo(source):
        repo = vcs_git.temp_clone(source)
        releases = vcs_git.list_module_releases(repo)

        if releases:
            last_release_num = releases[-1]
        else:
            print("No release has been done for " + module)
            # return so last_release_num can't be referenced before assignment
            return 1
    else:
        raise Exception(source + " does not exist on the repository.")

    # Get a single log between last release and HEAD
    # If there is one, then changes have been made
    logs = list(repo.iter_commits(last_release_num + "..HEAD", max_count=1))
    if logs:
        print("Changes have been made to " + module + " since release " + last_release_num)
    else:
        print("No changes have been made to " + module + " since most recent release " + last_release_num)

    shutil.rmtree(repo.working_tree_dir)
Esempio n. 2
0
    def verify_remote_repo(self):
        """Verifies there are no name conflicts with the remote repository.

        This checks whether or not there are any name conflicts between the
        intended module name and the modules that already exist on the remote
        repository.

        Sets the `_remote_repo_valid` boolean value to True if there are no
        conflicts.

        Raises:
            :class:`~dls_ade.exceptions.VerificationError`: If there is a \
                name conflict with the server.

        """
        if self._remote_repo_valid:
            return

        if vcs_git.is_server_repo(self._server_repo_path):
            err_message = ("The path {dir:s} already exists on gitolite,"
                           " cannot continue")
            raise VerificationError(
                err_message.format(dir=self._server_repo_path)
            )

        self._remote_repo_valid = True
Esempio n. 3
0
    def check_remote_repo_exists(self):
        """Check that the server_repo_path exists on the server.

        Raises:
            :class:`AssertionError`: If the test does not pass.

        """
        logging.debug("Checking server repo path given exists.")
        assert_true(vcs_git.is_server_repo(self._server_repo_path))
def push_repo(local_path):
    server_repo_path = local_path[len(NECESSARY_REPOS_DIR) + 1:]

    if not vcs_git.is_server_repo(server_repo_path):

        vcs_git.push_all_branches_and_tags(local_path, server_repo_path,
                                           "systest")

        print("Pushed to server:")
    else:
        print("This repository already exists on the server:")

    print(server_repo_path)
Esempio n. 5
0
    def _check_if_remote_repo_has_app(self, remote_repo_path):
        """Checks if the remote repository contains an app_nameApp folder.

        This checks whether or not there is already a folder with the name
        "app_nameApp" on the remote repository with the given gitolite
        repository path.

        Sets the `_remote_repo_valid` boolean value to True if there are no
        conflicts.

        Returns:
            bool: True if app exists, False otherwise.

        Raises:
            :class:`~dls_ade.exceptions.RemoteRepoError`: If given repo path \
                does not exist on gitolite.
                This should never be raised. There is a bug if it is!
            :class:`~dls_ade.exceptions.VCSGitError`: Issue with the vcs_git \
                function calls.

        """
        if not vcs_git.is_server_repo(remote_repo_path):
            # This should never get raised!
            err_message = ("Remote repo {repo:s} does not exist. Cannot "
                           "clone to determine if there is an app_name "
                           "conflict with {app_name:s}")
            err_message = err_message.format(repo=remote_repo_path,
                                             app_name=self._app_name)
            raise RemoteRepoError(err_message)

        temp_dir = ""
        exists = False
        try:
            repo = vcs_git.temp_clone(remote_repo_path)
            temp_dir = repo.working_tree_dir

            if os.path.exists(os.path.join(temp_dir, self._app_name + "App")):
                exists = True

        finally:
            try:
                if temp_dir:
                    shutil.rmtree(temp_dir)
            except OSError:
                pass

        return exists
Esempio n. 6
0
    def verify_remote_repo(self):
        """Verifies there are no name conflicts with the remote repository.

        This checks whether or not there are any name conflicts between the
        intended module and app names, and the modules that already exist on
        the remote repository.

        Sets the `_remote_repo_valid` boolean value to True if there are no
        conflicts.

        This method will fail (raise a VerificationError) if:
            - There is no remote repository to clone from
            - There is an app_name conflict with one of the remote
              paths

        Raises:
            :class:`~dls_ade.exceptions.VerificationError`: If there is an \
                issue with the remote repository.
            :class:`~dls_ade.exceptions.RemoteRepoError`: If the given server \
                path does not exist.
                This should never be raised. There is a bug if it is!

        """

        if self._remote_repo_valid:
            return

        if not vcs_git.is_server_repo(self._server_repo_path):
            err_message = ("The path {path:s} does not exist on gitolite, so "
                           "cannot clone from it")
            err_message = err_message.format(path=self._server_repo_path)
            raise VerificationError(err_message)

        conflicting_path = self._check_if_remote_repo_has_app(
            self._server_repo_path
        )

        if conflicting_path:
            err_message = ("The repository {path:s} has an app that conflicts "
                           "with app name: {app_name:s}")
            err_message = err_message.format(
                path=self._server_repo_path,
                app_name=self._app_name
            )
            raise VerificationError(err_message)

        self._remote_repo_valid = True
Esempio n. 7
0
    def set_server_repo_to_default(self):
        """Sets the given server repository to a default state.

        Note:
            If used on an existing server repository, all commit history will
            be overwritten.

        Raises:
            :class:`.SettingsError`: If default given but no server repo.
            :class:`dls_ade.exceptions.VCSGitError`: From \
                :mod:`~dls_ade.vcs_git` functions.

        """
        if not self._default_server_repo_path:
            return

        if not self._server_repo_path:
            raise SettingsError("If 'default_server_repo_path is set, then "
                                "'server_repo_path' must also be set.")

        logging.debug("Setting server repo to default.")
        logging.debug("'Default' server repo path: " +
                      self._default_server_repo_path)

        temp_repo = vcs_git.temp_clone(self._default_server_repo_path)
        vcs_git.delete_remote(temp_repo.working_tree_dir, "origin")

        if vcs_git.is_server_repo(self._server_repo_path):
            temp_repo.create_remote(
                    "origin",
                    os.path.join(vcs_git.GIT_SSH_ROOT, self._server_repo_path)
            )
            temp_repo.git.push("origin", temp_repo.active_branch, "-f")

        else:
            vcs_git.add_new_remote_and_push(self._server_repo_path,
                                            temp_repo.working_tree_dir)
Esempio n. 8
0
def get_module_creator_ioc(module_name, fullname=False):
    """Returns a :class:`ModuleCreatorIOC` subclass object.

    Returns an object of a subclass of :class:`ModuleCreatorIOC`, depending
    on the arguments given.

    IOC module name format:
        New-Style module (preferred):
            Format: "BL02I-VA-IOC-03"
                "<beamline>-<technical_area>-IOC-<ioc_number>"
            Alternative: "BL02I/VA/03", with fullname = True
                "<beamline>/<technical_area>/<ioc_number>", fullname = True

            If the alternative is used, if the IOC number is omitted
            (eg. <beamline>/<technical_area>) it defaults to "01"

        Old-Style module (deprecated, except for BL modules):
            Format: "BL02I/VA/03", with fullname = False (or omitted)
                "<beamline>/<technical_area>/<ioc_number>"

    Args:
        module_name: The name of the module.
        fullname: Create new-style module from old-style input.
            If True and module_name given in old-style format, then a
            new-style module is created.

    Returns:
        ModuleCreatorIOC: :class:`ModuleCreatorIOC` subclass object

    Raises:
        ParsingError: If the module cannot be split by '-' or '/'.

    """
    area = "ioc"

    dash_separated, cols = split_ioc_module_name(module_name)

    domain = cols[0]
    technical_area = cols[1]

    if technical_area == "BL":
        if dash_separated:
            app_name = module_name
            module_path = domain + "/" + app_name
        else:
            app_name = domain
            module_path = domain + "/" + technical_area

        return mc.ModuleCreatorWithApps(module_path, area,
                                        mt.ModuleTemplateIOCBL,
                                        app_name=app_name)

    module_template_cls = mt.ModuleTemplateIOC

    if dash_separated:
        app_name = module_name
        module_path = domain + "/" + app_name
        return mc.ModuleCreatorWithApps(module_path, area, module_template_cls,
                                        app_name=app_name)

    if len(cols) == 3 and cols[2]:
        ioc_number = cols[2]
    else:
        ioc_number = "01"

    app_name = "-".join([domain, technical_area, "IOC", ioc_number])

    if fullname:
        module_path = domain + "/" + app_name
        return mc.ModuleCreatorWithApps(module_path, area, module_template_cls,
                                        app_name=app_name)
    else:
        # This part is here to retain compatibility with "old-style" modules,
        # in which a single repo (or module) named "domain/technical_area"
        # contains multiple domain-technical_area-IOC-xxApp's. This code is
        # included in here to retain compatibility with the older svn scripts.
        # The naming is ambiguous, however. I will continue to use the name
        # 'module' to refer to the repo, but be aware that start_new_module and
        # module_creator don't have to actually create new modules (repos)
        # on the server in this instance.
        module_path = domain + "/" + technical_area
        server_repo_path = pathf.dev_module_path(module_path, area)
        if vcs_git.is_server_repo(server_repo_path):
            # Adding new App to old style "domain/tech_area" module that
            # already exists on the remote server.
            return mc.ModuleCreatorAddAppToModule(module_path, area,
                                                  module_template_cls,
                                                  app_name=app_name)
        else:
            # Otherwise, the behaviour is exactly the same as that given
            # by the ordinary IOC class as module_path is the only thing
            # that is different
            return mc.ModuleCreatorWithApps(module_path, area,
                                            module_template_cls,
                                            app_name=app_name)
def main():

    parser = make_parser()
    args = parser.parse_args()

    raw = set_raw_argument(args.raw)
    pathf.check_technical_area(args.area, args.module_name)
    check_parsed_args_compatible(args.releases, args.earlier_release, args.later_release, parser)
    check_releases_valid(args.releases, parser)

    source = pathf.dev_module_path(args.module_name, args.area)
    if vcs_git.is_server_repo(source):
        repo = vcs_git.temp_clone(source)
        releases = vcs_git.list_module_releases(repo)
        logging.debug(releases)
    else:
        raise Exception("Module " + args.module_name + " doesn't exist in " + source)

    # Set start and end releases and check they exist, set to defaults if not given
    start, end = set_log_range(args.module_name, args.releases, args.earlier_release, args.later_release, releases)

    # Create log info from log messages
    # log_info is a dictionary in the form {logs(list), commit_objects(dict), max_author_length(int)}
    log_info = get_log_messages(repo)

    if len(releases) > 0:

        if start == "":
            tag_start = releases[0]
        else:
            tag_start = start

        # Append tag info to log info from tag messages
        tags = get_tags_list(repo, tag_start, end, releases[-1])
        log_info = get_tag_messages(tags, log_info)

    # Check if there are any logs, exit if not
    if not log_info['logs']:
        print("No logs for " + args.module_name + " between releases " +
              args.earlier_release + " and " + args.later_release)
        return 0

    # Sort tags and commits chronologically by the UNIX time stamp in index 0
    log_info['logs'] = sorted(log_info['logs'], key=itemgetter(0))

    # Make list of printable log entries
    formatted_logs = format_log_messages(log_info, raw, args.verbose)

    if end == 'HEAD':
        print_bool = True
    else:
        print_bool = False

    release_marker = "(RELEASE: {})"
    for log in formatted_logs:
        if log.endswith(release_marker.format(end)):
            print_bool = True
        if print_bool:
            print(log)
        if log.endswith(release_marker.format(start)):
            break

    shutil.rmtree(repo.working_tree_dir)