Beispiel #1
0
def _get_channel_lines_for_channel(  # noqa: C901
    snap_channel_map: ChannelMap,
    channel_name: str,
    architecture: str,
    current_tick: str,
) -> Tuple[str, List[List[str]]]:
    channel_lines: List[List[str]] = list()

    channel_info = snap_channel_map.get_channel_info(channel_name)

    try:
        progressive_mapped_channel: Optional[
            MappedChannel] = snap_channel_map.get_mapped_channel(
                channel_name=channel_name,
                architecture=architecture,
                progressive=True)
    except ValueError:
        progressive_mapped_channel = None

    if progressive_mapped_channel is not None:
        progressive_revision = snap_channel_map.get_revision(
            progressive_mapped_channel.revision)

        if progressive_mapped_channel.progressive.percentage is None:
            raise RuntimeError("Unexpected null progressive percentage")
        else:
            percentage = progressive_mapped_channel.progressive.percentage

        if progressive_mapped_channel.progressive.current_percentage is None:
            current_percentage_fmt = _HINTS.UNKNOWN
            remaining_percentage_fmt = _HINTS.UNKNOWN
        else:
            current_percentage = (
                progressive_mapped_channel.progressive.current_percentage)
            current_percentage_fmt = f"{current_percentage:.0f}"
            remaining_percentage_fmt = f"{100 - current_percentage:.0f}"

        progressive_mapped_channel_line = _get_channel_line(
            mapped_channel=progressive_mapped_channel,
            revision=progressive_revision,
            channel_info=channel_info,
            hint=current_tick,
            progress_string=
            f"{current_percentage_fmt}{_HINTS.PROGRESSING_TO}{percentage:.0f}%",
        )
        # Setup progress for the actually released revision, this needs to be
        # calculated. But only show it if the channel is open.
        progress_string = (
            f"{remaining_percentage_fmt}{_HINTS.PROGRESSING_TO}{100 - percentage:.0f}%"
        )
    else:
        progress_string = _HINTS.NO_PROGRESS

    try:
        mapped_channel: Optional[
            MappedChannel] = snap_channel_map.get_mapped_channel(
                channel_name=channel_name,
                architecture=architecture,
                progressive=False)
    except ValueError:
        mapped_channel = None

    next_tick = current_tick
    if mapped_channel is not None:
        revision = snap_channel_map.get_revision(mapped_channel.revision)
        channel_lines.append(
            _get_channel_line(
                mapped_channel=mapped_channel,
                revision=revision,
                channel_info=channel_info,
                hint=current_tick,
                progress_string=progress_string,
            ))
        if channel_info.branch is None:
            next_tick = _HINTS.FOLLOWING
    # Show an empty entry if there is no specific channel information, but
    # only for <track>/<risks> (ignoring /<branch>).
    elif channel_info.branch is None:
        channel_lines.append(
            _get_channel_line(
                mapped_channel=None,
                revision=None,
                channel_info=channel_info,
                hint=current_tick,
                progress_string=_HINTS.NO_PROGRESS
                if current_tick == _HINTS.CLOSED else progress_string,
            ))

    if (os.getenv("SNAPCRAFT_EXPERIMENTAL_PROGRESSIVE_RELEASES")
            and progressive_mapped_channel is not None):
        channel_lines.append(progressive_mapped_channel_line)
        if channel_info.branch is None:
            next_tick = _HINTS.FOLLOWING

    return next_tick, channel_lines
Beispiel #2
0
    def setUp(self):
        super().setUp()

        # Our experimental environment variable is sticky
        self.useFixture(
            fixtures.EnvironmentVariable(
                "SNAPCRAFT_EXPERIMENTAL_PROGRESSIVE_RELEASES", None
            )
        )

        self.fake_store_login = fixtures.MockPatchObject(storeapi.StoreClient, "login")
        self.useFixture(self.fake_store_login)

        self.fake_store_register = fixtures.MockPatchObject(
            storeapi._sca_client.SCAClient, "register"
        )
        self.useFixture(self.fake_store_register)

        self.fake_store_account_info = fixtures.MockPatchObject(
            storeapi._sca_client.SCAClient,
            "get_account_information",
            return_value={
                "account_id": "abcd",
                "account_keys": list(),
                "snaps": {
                    "16": {
                        "snap-test": {
                            "snap-id": "snap-test-snap-id",
                            "status": "Approved",
                            "private": False,
                            "since": "2016-12-12T01:01Z",
                            "price": "0",
                        },
                        "basic": {
                            "snap-id": "basic-snap-id",
                            "status": "Approved",
                            "private": False,
                            "since": "2016-12-12T01:01Z",
                            "price": "0",
                        },
                    }
                },
            },
        )
        self.useFixture(self.fake_store_account_info)

        self.fake_store_status = fixtures.MockPatchObject(
            storeapi._sca_client.SCAClient, "snap_status", return_value=dict()
        )
        self.useFixture(self.fake_store_status)

        self.fake_store_revisions = fixtures.MockPatchObject(
            storeapi._sca_client.SCAClient, "snap_revisions", return_value=dict()
        )
        self.useFixture(self.fake_store_revisions)

        self.fake_store_release = fixtures.MockPatchObject(
            storeapi.StoreClient, "release"
        )
        self.useFixture(self.fake_store_release)

        self.fake_store_register_key = fixtures.MockPatchObject(
            storeapi._sca_client.SCAClient, "register_key"
        )
        self.useFixture(self.fake_store_register_key)

        # channel-map endpoint
        self.channel_map = ChannelMap.unmarshal(
            {
                "channel-map": [
                    {
                        "architecture": "amd64",
                        "channel": "2.1/beta",
                        "expiration-date": None,
                        "revision": 19,
                        "progressive": {"paused": None, "percentage": None},
                    }
                ],
                "revisions": [
                    {"architectures": ["amd64"], "revision": 19, "version": "10"}
                ],
                "snap": {
                    "name": "snap-test",
                    "channels": [
                        {
                            "branch": None,
                            "fallback": None,
                            "name": "2.1/stable",
                            "risk": "stable",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/stable",
                            "name": "2.1/candidate",
                            "risk": "candidate",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/candidate",
                            "name": "2.1/beta",
                            "risk": "beta",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/beta",
                            "name": "2.1/edge",
                            "risk": "edge",
                            "track": "2.1",
                        },
                    ],
                    "default-track": "2.1",
                },
            }
        )
        self.fake_store_get_snap_channel_map = fixtures.MockPatchObject(
            storeapi.StoreClient, "get_snap_channel_map", return_value=self.channel_map
        )
        self.useFixture(self.fake_store_get_snap_channel_map)

        # Uploading
        self.mock_tracker = mock.Mock(storeapi._status_tracker.StatusTracker)
        self.mock_tracker.track.return_value = {
            "code": "ready_to_release",
            "processed": True,
            "can_release": True,
            "url": "/fake/url",
            "revision": 19,
        }
        self.fake_store_upload_precheck = fixtures.MockPatchObject(
            storeapi.StoreClient, "upload_precheck"
        )
        self.useFixture(self.fake_store_upload_precheck)

        self.fake_store_upload = fixtures.MockPatchObject(
            storeapi.StoreClient, "upload", return_value=self.mock_tracker
        )
        self.useFixture(self.fake_store_upload)

        # Mock the snap command, pass through a select few.
        self.fake_check_output = fixtures.MockPatch(
            "subprocess.check_output", side_effect=mock_check_output
        )
        self.useFixture(self.fake_check_output)

        # Pretend that the snap command is available
        self.fake_package_installed = fixtures.MockPatch(
            "snapcraft.internal.repo.Repo.is_package_installed", return_value=True
        )
        self.useFixture(self.fake_package_installed)
Beispiel #3
0
    def setUp(self):
        super().setUp()

        # Our experimental environment variable is sticky
        self.useFixture(
            fixtures.EnvironmentVariable(
                "SNAPCRAFT_EXPERIMENTAL_PROGRESSIVE_RELEASES", None
            )
        )

        self.fake_store_login = fixtures.MockPatchObject(storeapi.StoreClient, "login")
        self.useFixture(self.fake_store_login)

        self.fake_store_register = fixtures.MockPatchObject(
            storeapi._dashboard_api.DashboardAPI, "register"
        )
        self.useFixture(self.fake_store_register)

        self.fake_store_account_info = fixtures.MockPatchObject(
            storeapi._dashboard_api.DashboardAPI,
            "get_account_information",
            return_value={
                "account_id": "abcd",
                "account_keys": list(),
                "snaps": {
                    "16": {
                        "snap-test": {
                            "snap-id": "snap-test-snap-id",
                            "status": "Approved",
                            "private": False,
                            "since": "2016-12-12T01:01Z",
                            "price": "0",
                        },
                        "basic": {
                            "snap-id": "basic-snap-id",
                            "status": "Approved",
                            "private": False,
                            "since": "2016-12-12T01:01Z",
                            "price": "0",
                        },
                    }
                },
            },
        )
        self.useFixture(self.fake_store_account_info)

        self.fake_store_status = fixtures.MockPatchObject(
            storeapi._dashboard_api.DashboardAPI, "snap_status", return_value=dict()
        )
        self.useFixture(self.fake_store_status)

        self.fake_store_release = fixtures.MockPatchObject(
            storeapi.StoreClient, "release"
        )
        self.useFixture(self.fake_store_release)

        self.fake_store_register_key = fixtures.MockPatchObject(
            storeapi._dashboard_api.DashboardAPI, "register_key"
        )
        self.useFixture(self.fake_store_register_key)

        # channel-map endpoint
        self.channel_map = ChannelMap.unmarshal(
            {
                "channel-map": [
                    {
                        "architecture": "amd64",
                        "channel": "2.1/beta",
                        "expiration-date": None,
                        "revision": 19,
                        "progressive": {
                            "paused": None,
                            "percentage": None,
                            "current-percentage": None,
                        },
                    },
                    {
                        "architecture": "amd64",
                        "channel": "2.0/beta",
                        "expiration-date": None,
                        "revision": 18,
                        "progressive": {
                            "paused": None,
                            "percentage": None,
                            "current-percentage": None,
                        },
                    },
                ],
                "revisions": [
                    {"architectures": ["amd64"], "revision": 19, "version": "10"},
                    {"architectures": ["amd64"], "revision": 18, "version": "10"},
                ],
                "snap": {
                    "name": "snap-test",
                    "channels": [
                        {
                            "branch": None,
                            "fallback": None,
                            "name": "2.1/stable",
                            "risk": "stable",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/stable",
                            "name": "2.1/candidate",
                            "risk": "candidate",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/candidate",
                            "name": "2.1/beta",
                            "risk": "beta",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": "2.1/beta",
                            "name": "2.1/edge",
                            "risk": "edge",
                            "track": "2.1",
                        },
                        {
                            "branch": None,
                            "fallback": None,
                            "name": "2.0/stable",
                            "risk": "stable",
                            "track": "2.0",
                        },
                        {
                            "branch": None,
                            "fallback": "2.0/stable",
                            "name": "2.0/candidate",
                            "risk": "candidate",
                            "track": "2.0",
                        },
                        {
                            "branch": None,
                            "fallback": "2.0/candidate",
                            "name": "2.0/beta",
                            "risk": "beta",
                            "track": "2.0",
                        },
                        {
                            "branch": None,
                            "fallback": "2.0/beta",
                            "name": "2.0/edge",
                            "risk": "edge",
                            "track": "2.0",
                        },
                    ],
                    "default-track": "2.1",
                    "tracks": [
                        {
                            "name": "2.0",
                            "status": "default",
                            "creation-date": "2019-10-17T14:11:59Z",
                            "version-pattern": "2\\.*",
                        },
                        {
                            "name": "latest",
                            "status": "active",
                            "creation-date": None,
                            "version-pattern": None,
                        },
                    ],
                },
            }
        )
        self.fake_store_get_snap_channel_map = fixtures.MockPatchObject(
            storeapi.StoreClient, "get_snap_channel_map", return_value=self.channel_map
        )
        self.useFixture(self.fake_store_get_snap_channel_map)

        self.releases = Releases.unmarshal(
            {
                "revisions": [
                    {
                        "architectures": ["i386"],
                        "base": "core20",
                        "build_url": None,
                        "confinement": "strict",
                        "created_at": " 2016-09-27T19:23:40Z",
                        "grade": "stable",
                        "revision": 2,
                        "sha3-384": "a9060ef4872ccacbfa440617a76fcd84967896b28d0d1eb7571f00a1098d766e7e93353b084ba6ad841d7b14b95ede48",
                        "size": 20,
                        "status": "Published",
                        "version": "2.0.1",
                    },
                    {
                        "architectures": ["amd64"],
                        "base": "core20",
                        "build_url": None,
                        "confinement": "strict",
                        "created_at": "2016-09-27T18:38:43Z",
                        "grade": "stable",
                        "revision": 1,
                        "sha3-384": "a9060ef4872ccacbfa440617a76fcd84967896b28d0d1eb7571f00a1098d766e7e93353b084ba6ad841d7b14b95ede48",
                        "size": 20,
                        "status": "Published",
                        "version": "2.0.2",
                    },
                ],
                "releases": [
                    {
                        "architecture": "amd64",
                        "branch": None,
                        "channel": "latest/stable",
                        "expiration-date": None,
                        "revision": 1,
                        "risk": "stable",
                        "track": "latest",
                        "when": "2020-02-12T17:51:40.891996Z",
                    },
                    {
                        "architecture": "i386",
                        "branch": None,
                        "channel": "latest/stable",
                        "expiration-date": None,
                        "revision": None,
                        "risk": "stable",
                        "track": "latest",
                        "when": "2020-02-11T17:51:40.891996Z",
                    },
                    {
                        "architecture": "amd64",
                        "branch": None,
                        "channel": "latest/edge",
                        "expiration-date": None,
                        "revision": 1,
                        "risk": "stable",
                        "track": "latest",
                        "when": "2020-01-12T17:51:40.891996Z",
                    },
                ],
            }
        )
        self.fake_store_get_releases = fixtures.MockPatchObject(
            storeapi.StoreClient, "get_snap_releases", return_value=self.releases
        )
        self.useFixture(self.fake_store_get_releases)

        # Uploading
        self.mock_tracker = mock.Mock(storeapi._status_tracker.StatusTracker)
        self.mock_tracker.track.return_value = {
            "code": "ready_to_release",
            "processed": True,
            "can_release": True,
            "url": "/fake/url",
            "revision": 19,
        }
        self.fake_store_upload_precheck = fixtures.MockPatchObject(
            storeapi.StoreClient, "upload_precheck"
        )
        self.useFixture(self.fake_store_upload_precheck)

        self.fake_store_upload = fixtures.MockPatchObject(
            storeapi.StoreClient, "upload", return_value=self.mock_tracker
        )
        self.useFixture(self.fake_store_upload)

        # Mock the snap command, pass through a select few.
        self.fake_check_output = fixtures.MockPatch(
            "subprocess.check_output", side_effect=mock_check_output
        )
        self.useFixture(self.fake_check_output)

        # Pretend that the snap command is available
        self.fake_package_installed = fixtures.MockPatch(
            "snapcraft.internal.repo.Repo.is_package_installed", return_value=True
        )
        self.useFixture(self.fake_package_installed)
Beispiel #4
0
def _get_channel_lines_for_channel(snap_channel_map: ChannelMap,
                                   channel_name: str,
                                   architecture: str) -> List[List[str]]:
    channel_lines: List[List[str]] = list()

    channel_info = snap_channel_map.get_channel_info(channel_name)

    hint = _get_channel_hint(
        channel_map=snap_channel_map.channel_map,
        fallback=channel_info.fallback,
        architecture=architecture,
    )

    try:
        progressive_mapped_channel: Optional[
            MappedChannel] = snap_channel_map.get_mapped_channel(
                channel_name=channel_name,
                architecture=architecture,
                progressive=True)
    except ValueError:
        progressive_mapped_channel = None

    if progressive_mapped_channel is not None:
        progressive_revision = snap_channel_map.get_revision(
            progressive_mapped_channel.revision)

        progressive_mapped_channel_line = _get_channel_line(
            mapped_channel=progressive_mapped_channel,
            revision=progressive_revision,
            channel_info=channel_info,
            hint=hint,
            progress_string=
            f"{_HINTS.PROGRESSING_TO} {progressive_mapped_channel.progressive.percentage:.0f}%",
        )
        if progressive_mapped_channel.progressive.percentage is None:
            percentage = 0.0
        else:
            percentage = progressive_mapped_channel.progressive.percentage
        # Setup progress for the actually released revision, this needs to be
        # calculated. But only show it if the channel is open.
        progress_string = "{} {:.0f}%".format(_HINTS.PROGRESSING_TO,
                                              100 - percentage)
    else:
        progress_string = _HINTS.NO_PROGRESS

    try:
        mapped_channel: Optional[
            MappedChannel] = snap_channel_map.get_mapped_channel(
                channel_name=channel_name,
                architecture=architecture,
                progressive=False)
    except ValueError:
        mapped_channel = None

    if mapped_channel is not None:
        revision = snap_channel_map.get_revision(mapped_channel.revision)
        channel_lines.append(
            _get_channel_line(
                mapped_channel=mapped_channel,
                revision=revision,
                channel_info=channel_info,
                hint=hint,
                progress_string=progress_string,
            ))
    # Don't show empty branches
    elif channel_info.branch is None:
        channel_lines.append(
            _get_channel_line(
                mapped_channel=None,
                revision=None,
                channel_info=channel_info,
                hint=hint,
                progress_string=_HINTS.NO_PROGRESS
                if hint == _HINTS.CLOSED else progress_string,
            ))

    if (os.getenv("SNAPCRAFT_EXPERIMENTAL_PROGRESSIVE_RELEASES")
            and progressive_mapped_channel is not None):
        channel_lines.append(progressive_mapped_channel_line)

    return channel_lines