예제 #1
0
    def test_changelog_last_items(self):
        """Test last items from changelog."""
        # on fixture changelog
        parser = ChangelogParser(parent_folder="test/fixtures")
        last_items = parser.last_items(3)
        self.assertIsInstance(last_items, str)

        # on repository changelog
        parser = ChangelogParser()
        last_items = parser.last_items(3)
        self.assertIsInstance(last_items, str)
예제 #2
0
    def test_changelog_parser(self):
        """ Test we can parse a changelog with a regex. """
        self.assertTrue(ChangelogParser.has_changelog())
        parser = ChangelogParser(CHANGELOG_REGEXP)
        self.assertIsNone(parser.content("0.0.0"), "")

        expected = (
            "* Tag using a wrong format DD/MM/YYYY according to Keep A Changelog\n"
            '* Tag without "v" prefix\n'
            "* Add a CHANGELOG.md file for testing")
        self.assertEqual(parser.content("0.1.2"), expected)

        expected = (
            "\n "
            "Version 0.1.2 :\n "
            "* Tag using a wrong format DD/MM/YYYY according to Keep A Changelog\n "
            '* Tag without "v" prefix\n '
            "* Add a CHANGELOG.md file for testing\n"
            "\n")
        self.assertEqual(parser.last_items(1), expected)

        expected = """
 Version 0.1.2 :
 * Tag using a wrong format DD/MM/YYYY according to Keep A Changelog
 * Tag without "v" prefix
 * Add a CHANGELOG.md file for testing

 Version v0.1.1 :
 * Tag using a correct format YYYY-MM-DD according to Keep A Changelog
 * Tag with a "v" prefix to check the regular expression
 * Previous version

 Version 0.1.0 :
 * Very old version

"""
        self.assertEqual(parser.last_items(3), expected)
예제 #3
0
    def test_release_changelog(self):
        """Test if changelog in metadata.txt inside zipped plugin after release command."""
        # variables
        cli_config_changelog = Path(
            "test/fixtures/.qgis-plugin-ci-test-changelog.yaml")
        version_to_release = "0.1.2"

        # load specific parameters
        with cli_config_changelog.open() as in_cfg:
            arg_dict = yaml.safe_load(in_cfg)
        parameters = Parameters(arg_dict)
        self.assertIsInstance(parameters, Parameters)

        # get output zip path
        archive_name = parameters.archive_name(
            plugin_name=parameters.plugin_path,
            release_version=version_to_release)

        # extract last items from changelog
        parser = ChangelogParser()
        self.assertTrue(parser.has_changelog())
        changelog_lastitems = parser.last_items(
            count=parameters.changelog_number_of_entries)

        # Include a changelog
        release(
            parameters=parameters,
            release_version=version_to_release,
            allow_uncommitted_changes=True,
        )

        # open archive and compare
        with ZipFile(archive_name, "r") as zip_file:
            data = zip_file.read(f"{parameters.plugin_path}/metadata.txt")

        # Changelog
        self.assertGreater(
            data.find(bytes(changelog_lastitems, "utf8")),
            0,
            f"changelog detection failed in release: {data}",
        )

        # Commit number
        self.assertEqual(1, len(re.findall(r"commitNumber=\d+", str(data))))

        # Commit sha1 not in the metadata.txt
        self.assertEqual(0, len(re.findall(r"commitSha1=\d+", str(data))))
예제 #4
0
def create_archive(
    parameters: Parameters,
    release_version: str,
    archive_name: str,
    add_translations: bool = False,
    allow_uncommitted_changes: bool = False,
    is_prerelease: bool = False,
    raise_min_version: str = None,
    disable_submodule_update: bool = False,
):

    repo = git.Repo()

    top_tar_handle, top_tar_file = mkstemp(suffix=".tar")

    # keep track of current state
    initial_stash = None
    diff = repo.index.diff(None)
    if diff:
        print("Uncommitted changes:")
        for diff in diff:
            print(diff)
        if not allow_uncommitted_changes:
            raise UncommitedChanges(
                "You have uncommitted changes. Stash or commit them or use --allow-uncommitted-changes."
            )
        else:
            initial_stash = repo.git.stash("create")

    # changelog
    if parameters.changelog_include:
        parser = ChangelogParser(parameters.changelog_regexp)
        if parser.has_changelog():
            try:
                content = parser.last_items(
                    parameters.changelog_number_of_entries)
                if content:
                    replace_in_file(
                        "{}/metadata.txt".format(parameters.plugin_path),
                        r"^changelog=.*$",
                        "changelog={}".format(content),
                    )
            except Exception as e:
                # Do not fail the release process if something is wrong when parsing the changelog
                replace_in_file(
                    "{}/metadata.txt".format(parameters.plugin_path),
                    r"^changelog=.*$",
                    "",
                )
                print(
                    "An exception occurred while parsing the changelog file : {}"
                    .format(e))
    else:
        # Remove the changelog line
        replace_in_file("{}/metadata.txt".format(parameters.plugin_path),
                        r"^changelog=.*$", "")

    # set version in metadata
    replace_in_file(
        "{}/metadata.txt".format(parameters.plugin_path),
        r"^version=.*$",
        "version={}".format(release_version),
    )

    # set the plugin as experimental on a pre-release
    if is_prerelease:
        replace_in_file(
            "{}/metadata.txt".format(parameters.plugin_path),
            r"^experimental=.*$",
            "experimental={}".format(True if is_prerelease else False),
        )

    if raise_min_version:
        replace_in_file(
            "{}/metadata.txt".format(parameters.plugin_path),
            r"^qgisMinimumVersion=.*$",
            "qgisMinimumVersion={}".format(raise_min_version),
        )

    # replace any DEBUG=False in all Python files
    if not is_prerelease:
        for file in glob("{}/**/*.py".format(parameters.plugin_path),
                         recursive=True):
            replace_in_file(file, r"^DEBUG\s*=\s*True", "DEBUG = False")

    # keep track of current state
    try:
        stash = repo.git.stash("create")
    except git.exc.GitCommandError:
        stash = "HEAD"
    if stash == "" or stash is None:
        stash = "HEAD"
    # create TAR archive
    print("archive plugin with stash: {}".format(stash))
    repo.git.archive(stash, "-o", top_tar_file, parameters.plugin_path)
    # adding submodules
    for submodule in repo.submodules:
        _, sub_tar_file = mkstemp(suffix=".tar")
        if submodule.path.split("/")[0] != parameters.plugin_path:
            print("skipping submodule not in plugin source directory ({})".
                  format(submodule.name))
            continue
        if not disable_submodule_update:
            submodule.update(init=True)
        sub_repo = submodule.module()
        print("archive submodule:", sub_repo)
        sub_repo.git.archive("HEAD", "--prefix", "{}/".format(submodule.path),
                             "-o", sub_tar_file)
        with tarfile.open(top_tar_file, mode="a") as tt:
            with tarfile.open(sub_tar_file, mode="r:") as st:
                for m in st.getmembers():
                    # print('adding', m, m.type, m.isfile())
                    if not m.isfile():
                        continue
                    tt.add(m.name)

    # add translation files
    if add_translations:
        with tarfile.open(top_tar_file, mode="a") as tt:
            print("adding translations")
            for file in glob("{}/i18n/*.qm".format(parameters.plugin_path)):
                print("  adding translation: {}".format(
                    os.path.basename(file)))
                # https://stackoverflow.com/a/48462950/1548052
                tt.add(file)

    # compile qrc files
    pyqt5ac.main(ioPaths=[[
        "{}/*.qrc".format(parameters.plugin_path),
        "{}/%%FILENAME%%_rc.py".format(parameters.plugin_path),
    ]])
    for file in glob("{}/*_rc.py".format(parameters.plugin_path)):
        with tarfile.open(top_tar_file, mode="a") as tt:
            print("  adding resource: {}".format(file))
            # https://stackoverflow.com/a/48462950/1548052
            tt.add(file)

    # converting to ZIP
    # why using TAR before? because it provides the prefix and makes things easier
    with zipfile.ZipFile(file=archive_name,
                         mode="w",
                         compression=zipfile.ZIP_DEFLATED) as zf:
        # adding the content of TAR archive
        with tarfile.open(top_tar_file, mode="r:") as tt:
            for m in tt.getmembers():
                if m.isdir():
                    continue
                f = tt.extractfile(m)
                fl = f.read()
                fn = m.name
                zf.writestr(fn, fl)

    print("-------")
    print("files in ZIP archive ({}):".format(archive_name))
    with zipfile.ZipFile(file=archive_name, mode="r") as zf:
        for f in zf.namelist():
            print(f)
    print("-------")

    # checkout to reset changes
    if initial_stash:
        repo.git.reset("--hard", initial_stash)
        repo.git.reset("HEAD^")
    else:
        repo.git.checkout("--", ".")