def prepare_entrypoint_documentation(data):
    """Place the generated entrypoint doc in the source structure."""
    if data['name'] != 'zest.releaser':
        # We're available everywhere, but we're only intended for
        # zest.releaser internal usage.
        return
    target = os.path.join(data['reporoot'], 'doc', 'source',
                          'entrypoints.rst')
    marker = '.. ### AUTOGENERATED FROM HERE ###'
    result = []
    lines, encoding = read_text_file(target)
    for line in lines.split('\n'):
        line = line.rstrip()
        if line == marker:
            break
        result.append(line)
    result.append(marker)
    result.append('')

    for name, datadict in (
            ('prerelease', prerelease.DATA),
            ('release', release.DATA),
            ('postrelease', postrelease.DATA)):
        heading = '%s data dict items' % name.capitalize()
        result.append(heading)
        result.append('-' * len(heading))
        result.append('')
        for key in sorted(datadict.keys()):
            result.append(key)
            result.append('    ' + datadict[key])
            result.append('')

    write_text_file(target, '\n'.join(result), encoding)
    print("Wrote entry point documentation to %s" % target)
Beispiel #2
0
 def _update_history(self):
     """Update the history file"""
     version = self.data['new_version']
     history = self.vcs.history_file()
     if not history:
         logger.warn("No history file found")
         return
     history_lines = read_text_file(history).split('\n')
     headings = utils.extract_headings_from_history(history_lines)
     if not len(headings):
         logger.warn("No detectable existing version headings in the "
                     "history file.")
         inject_location = 0
         underline_char = '-'
     else:
         first = headings[0]
         inject_location = first['line']
         underline_line = first['line'] + 1
         try:
             underline_char = history_lines[underline_line][0]
         except IndexError:
             logger.debug("No character on line below header.")
             underline_char = '-'
     header = '%s (unreleased)' % version
     inject = [header,
               underline_char * len(header),
               '',
               self.data['nothing_changed_yet'],
               '',
               '']
     history_lines[inject_location:inject_location] = inject
     contents = '\n'.join(history_lines)
     write_text_file(history, contents)
     logger.info("Injected new section into the history: %r", header)
Beispiel #3
0
 def _write_history(self):
     """Write previously-calculated history lines back to the file"""
     if self.data['history_file'] is None:
         return
     contents = '\n'.join(self.data['history_lines'])
     history = self.data['history_file']
     write_text_file(history, contents)
     logger.info("History file %s updated.", history)
Beispiel #4
0
def cleanup_changelog(data):
    """Cleanup empty headers.

    We call this twice: in prereleaser.before and prereleaser.middle.

    In 'before', we are too early and zest.releaser has not looked for
    the history file yet.  But we try 'CHANGES.rst' ourselves.

    In 'middle' we are a bit too late, as zest.releaser has already
    complained when it found the NOTHING_CHANGED_YET value in the
    history.

    So we call this twice, which should be fine.

    """
    # The history_file is probably not set yet, as we are called too early.
    # That might change subtly in future zest.releaser versions, so let's check
    # it anyway.
    history_file = data.get('history_file')
    if history_file:
        contents = '\n'.join(data['history_lines'])
        encoding = data['history_encoding']
    else:
        # We do not want to copy the logic from zest.releaser that tries to
        # find the history file, but we can check the most obvious spot.
        history_file = 'CHANGES.rst'
        if not os.path.exists(history_file):
            print('Cannot cleanup history, will try again later.')
            return
        contents, encoding = read_text_file(history_file)
    orig_contents = contents
    changed = False
    for header in ALL_HEADERS:
        if header in contents:
            contents = contents.replace(header, '')
            changed = True
    if not changed:
        return
    write_text_file(
        history_file, contents, encoding=encoding)
    print("Cleaned up empty headers from history file {}".format(history_file))
    # Update the data, otherwise our work may get overwritten.
    data['history_lines'] = contents.split('\n')
    if not os.path.isdir('.git'):
        print('Not a git checkout, cannot commit.')
        return
    g = git.Git('.')
    message = "Cleaned up empty headers from changelog.\n\n[ci skip]"
    print(g.diff(history_file))
    msg = "Commit changes?"
    if not ask(msg, default=True):
        # Restore original contents.
        write_text_file(
            history_file, orig_contents, encoding=encoding)
        sys.exit()
    print("Committing changes.")
    print(g.add(history_file))
    print(g.commit(message=message))
Beispiel #5
0
 def _write_history(self):
     """Write previously-calculated history lines back to the file"""
     if self.data['history_file'] is None:
         return
     contents = '\n'.join(self.data['history_lines'])
     history = self.data['history_file']
     write_text_file(
         history, contents, encoding=self.data['history_encoding'])
     logger.info("History file %s updated.", history)
Beispiel #6
0
 def _update_python_file_version(self, version):
     setup_cfg = pypi.SetupConfig()
     filename = setup_cfg.python_file_with_version()
     lines, encoding = utils.read_text_file(filename)
     lines = lines.split('\n')
     for index, line in enumerate(lines):
         match = UNDERSCORED_VERSION_PATTERN.search(line)
         if match:
             lines[index] = "__version__ = '%s'" % version
     contents = '\n'.join(lines)
     utils.write_text_file(filename, contents, encoding)
     logger.info("Set __version__ in %s to %r", filename, version)
Beispiel #7
0
 def _update_python_file_version(self, version):
     filename = self.setup_cfg.python_file_with_version()
     lines, encoding = utils.read_text_file(
         filename,
         fallback_encoding=self.fallback_encoding,
     )
     for index, line in enumerate(lines):
         match = UNDERSCORED_VERSION_PATTERN.search(line)
         if match:
             lines[index] = "__version__ = '%s'" % version
     contents = '\n'.join(lines)
     utils.write_text_file(filename, contents, encoding)
     logger.info("Set __version__ in %s to '%s'", filename, version)
Beispiel #8
0
    def _update_version(self, version):
        """Find out where to change the version and change it.

        There are three places where the version can be defined. The first one
        is an explicitly defined Python file with a ``__version__``
        attribute. The second one is some version.txt that gets read by
        setup.py. The third is directly in setup.py.
        """
        if self.get_python_file_version():
            self._update_python_file_version(version)
            return

        version_filenames = ['version']
        version_filenames.extend(
            ['.'.join(['version', extension]) for extension in TXT_EXTENSIONS])
        versionfile = self.filefind(version_filenames)
        if versionfile:
            # We have a version.txt file but does it match the setup.py
            # version (if any)?
            setup_version = self.get_setup_py_version()
            if not setup_version or (setup_version
                                     == self.get_version_txt_version()):
                with open(versionfile, 'w') as f:
                    f.write(version + '\n')
                logger.info("Changed %s to %r", versionfile, version)
                return

        good_version = "version = '%s'" % version
        line_number = 0
        setup_lines, encoding = utils.read_text_file('setup.py')
        setup_lines = setup_lines.split('\n')
        for line_number, line in enumerate(setup_lines):
            if VERSION_PATTERN.search(line):
                logger.debug("Matching version line found: %r", line)
                if line.startswith(' '):
                    # oh, probably '    version = 1.0,' line.
                    indentation = line.split('version')[0]
                    # Note: no spaces around the '='.
                    good_version = indentation + "version='%s'," % version
                setup_lines[line_number] = good_version
                utils.write_text_file('setup.py', '\n'.join(setup_lines),
                                      encoding)
                logger.info("Set setup.py's version to %r", version)
                return

        logger.error(
            "We could read a version from setup.py, but could not write it "
            "back. See "
            "http://zestreleaser.readthedocs.io/en/latest/versions.html "
            "for hints.")
        raise RuntimeError("Cannot set version")
def fillchangelog(context):
    default_location = None
    setup_cfg = pypi.SetupConfig()
    config = setup_cfg.config
    if config and config.has_option('zest.releaser', 'history_file'):
        default_location = config.get('zest.releaser', 'history_file')

    vcs = zest.releaser.choose.version_control()
    history_file = vcs.history_file(location=default_location)
    if history_file:

        try:
            found = zest.releaser.utils.get_last_tag(vcs)
            log_command = vcs.cmd_log_since_tag(found)
        except SystemExit:
            log_command = get_all_commits_command(vcs)

        if log_command:
            data = execute_command(log_command)
            pretty_data = prettyfy_logs(data, vcs)

            print('These are all the commits since the last tag:')
            print('')
            print('\n'.join(pretty_data))

            if zest.releaser.utils.ask('Do you want to add those commits to the CHANGES file?', True):
                new_history_lines = []
                history_lines, history_encoding = read_text_file(history_file)
                history_lines = history_lines.split('\n')
                for line in history_lines:
                    current_position = history_lines.index(line)
                    new_history_lines.append(line)
                    if line.lower().find('unreleased') != -1:
                        # current_position + 1 == ----------------
                        # current_position + 2 ==   blank
                        # current_position + 3 == - Nothing changed yet.
                        # current_position + 4 ==   blank
                        new_history_lines.append(history_lines[current_position + 1])
                        new_history_lines.append(history_lines[current_position + 2])
                        new_history_lines.extend(pretty_data)
                        new_history_lines.extend(history_lines[current_position + 4:])
                        break

                contents = '\n'.join(new_history_lines)
                write_text_file(history_file, contents)
                msg = 'Update changelog'
                commit_cmd = vcs.cmd_commit(msg)
                commit = execute_command(commit_cmd)
                print(commit)
    else:
        print('History file not found. Skipping.')
Beispiel #10
0
def updateBuildoutChangeLogs(history_lines, history_encoding, headings, changelogs, package, version):
    inject_location = headings[0]['line']
    inject = ['', '- %s %s' % (package, version)]
    indentchangelogs = []
    for changelog in changelogs:
        if changelog:
            changelog = '    %s' % changelog
        indentchangelogs.append(changelog)
    inject.extend(indentchangelogs)
    inject.append('')
    if history_lines[inject_location+3] == '- Nothing changed yet.':
        del history_lines[inject_location+3:inject_location+6]
    history_lines[inject_location+2:inject_location+2] = inject
    contents = u'\n'.join(history_lines)
    utils.write_text_file(BUILDOUTHISTORYFILE, contents, history_encoding)
def prepare_entrypoint_documentation(data):
    """Place the generated entrypoint doc in the source structure."""
    if data['name'] != 'zest.releaser':
        # We're available everywhere, but we're only intended for
        # zest.releaser internal usage.
        return
    target = os.path.join(data['reporoot'], 'doc', 'source',
                          'entrypoints.rst')
    marker = '.. ### AUTOGENERATED FROM HERE ###'
    result = []
    lines, encoding = read_text_file(target)
    for line in lines:
        line = line.rstrip()
        if line == marker:
            break
        result.append(line)
    result.append(marker)
    result.append('')

    for name, datadict in (
            ('common', baserelease.DATA),
            ('prerelease', prerelease.DATA),
            ('release', release.DATA),
            ('postrelease', postrelease.DATA),
            ('addchangelogentry', addchangelogentry.DATA),
            ('bumpversion', bumpversion.DATA),
    ):
        if name == 'common':
            heading = '%s data dict items' % name.capitalize()
        else:
            # quote the command name
            heading = '``%s`` data dict items' % name
        result.append(heading)
        result.append('-' * len(heading))
        result.append('')
        if name == 'common':
            result.append('These items are shared among all commands.')
            result.append('')
        for key in sorted(datadict.keys()):
            if name != 'common' and datadict[key] == baserelease.DATA.get(key):
                # The key is already in common data, with the same value.
                continue
            result.append(key)
            result.append('    ' + datadict[key])
            result.append('')

    write_text_file(target, '\n'.join(result), encoding)
    print("Wrote entry point documentation to %s" % target)
Beispiel #12
0
    def _update_python_file_version(self, version):
        filename = self.setup_cfg.python_file_with_version()
        lines, encoding = utils.read_text_file(
            filename,
            fallback_encoding=self.fallback_encoding,
        )
        good_version = "__version__ = '%s'" % version
        for index, line in enumerate(lines):
            if UNDERSCORED_VERSION_PATTERN.search(line):
                lines[index] = (
                    good_version.replace("'", '"')
                    if '"' in line
                    else good_version
                )

        contents = '\n'.join(lines)
        utils.write_text_file(filename, contents, encoding)
        logger.info("Set __version__ in %s to '%s'", filename, version)
def prepare_entrypoint_documentation(data):
    """Place the generated entrypoint doc in the source structure."""
    if data['name'] != 'zest.releaser':
        # We're available everywhere, but we're only intended for
        # zest.releaser internal usage.
        return
    target = os.path.join(data['reporoot'], 'doc', 'source',
                          'entrypoints.rst')
    marker = '.. ### AUTOGENERATED FROM HERE ###'
    result = []
    lines, encoding = read_text_file(target)
    for line in lines.split('\n'):
        line = line.rstrip()
        if line == marker:
            break
        result.append(line)
    result.append(marker)
    result.append('')

    for name, datadict in (
            ('prerelease', prerelease.DATA),
            ('release', release.DATA),
            ('postrelease', postrelease.DATA),
            ('addchangelogentry', addchangelogentry.DATA),
            ('bumpversion', bumpversion.DATA),
            ):
        heading = '%s data dict items' % name.capitalize()
        result.append(heading)
        result.append('-' * len(heading))
        result.append('')
        for key in sorted(datadict.keys()):
            result.append(key)
            result.append('    ' + datadict[key])
            result.append('')

    write_text_file(target, '\n'.join(result), encoding)
    print("Wrote entry point documentation to %s" % target)
Beispiel #14
0
    def _update_version(self, version):
        """Find out where to change the version and change it.

        There are three places where the version can be defined. The first one
        is an explicitly defined Python file with a ``__version__``
        attribute. The second one is some version.txt that gets read by
        setup.py. The third is directly in setup.py.
        """
        if self.get_python_file_version():
            setup_cfg = pypi.SetupConfig()
            filename = setup_cfg.python_file_with_version()
            lines, encoding = utils.read_text_file(filename)
            lines = lines.split('\n')
            for index, line in enumerate(lines):
                match = UNDERSCORED_VERSION_PATTERN.search(line)
                if match:
                    lines[index] = "__version__ = '%s'" % version
            contents = '\n'.join(lines)
            utils.write_text_file(filename, contents, encoding)
            logger.info("Set __version__ in %s to %r", filename, version)
            return

        version_filenames = ['version']
        for extension in TXT_EXTENSIONS:
            version_filenames.append('.'.join(['version', extension]))
        versionfile = self.filefind(version_filenames)
        if versionfile:
            # We have a version.txt file but does it match the setup.py
            # version (if any)?
            setup_version = self.get_setup_py_version()
            if not setup_version or (setup_version ==
                                     self.get_version_txt_version()):
                open(versionfile, 'w').write(version + '\n')
                logger.info("Changed %s to %r", versionfile, version)
                return

        good_version = "version = '%s'" % version
        line_number = 0
        setup_lines, encoding = utils.read_text_file('setup.py')
        setup_lines = setup_lines.split('\n')
        for line_number, line in enumerate(setup_lines):
            match = VERSION_PATTERN.search(line)
            if match:
                logger.debug("Matching version line found: %r", line)
                if line.startswith(' '):
                    # oh, probably '    version = 1.0,' line.
                    indentation = line.split('version')[0]
                    # Note: no spaces around the '='.
                    good_version = indentation + "version='%s'," % version
                setup_lines[line_number] = good_version
                contents = '\n'.join(setup_lines)
                utils.write_text_file('setup.py', contents, encoding)
                logger.info("Set setup.py's version to %r", version)
                return

        logger.error(
            "We could read a version from setup.py, but could not write it " +
            "back. See " +
            "http://zestreleaser.readthedocs.org/en/latest/versions.html " +
            "for hints.")
        raise RuntimeError("Cannot set version")