Skip to content

Commit

Permalink
Allow switch kwarg in refresh to switch to local charms
Browse files Browse the repository at this point in the history
Check if the switch param is pointing to a local charm. If it is, run
local_refresh as if it were provided

This is how the Juju CLI works, which was missing from pylibjuju.
Replicate this.

Also push url parsing of switch kwarg behind a check if it's local
charm, meaning we avoid the possibility where we attempt to parse a path
as if it were a url

Resolves #967
  • Loading branch information
jack-w-shaw committed Oct 23, 2023
1 parent 4fcebc2 commit ef085c3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 7 deletions.
15 changes: 8 additions & 7 deletions juju/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import hashlib
import json
import logging
import pathlib
from pathlib import Path

from . import model, tag, utils, jasyncio
from .url import URL, Schema
from .status import derive_status
from .annotationhelper import _get_annotations, _set_annotations
from .client import client
from .errors import JujuError, JujuApplicationConfigError
from .bundle import get_charm_series
from .bundle import get_charm_series, is_local_charm
from .placement import parse as parse_placement
from .origin import Channel

Expand Down Expand Up @@ -654,14 +654,14 @@ async def refresh(
if charm_url_origin_result.error is not None:
err = charm_url_origin_result.error
raise JujuError("%s : %s" % (err.code, err.message))
charm_url = switch or charm_url_origin_result.url
origin = charm_url_origin_result.charm_origin

if path is not None:
if path is not None or is_local_charm(switch):
await self.local_refresh(origin, force, force_series,
force_units, path, resources)
force_units, path or switch, resources)
return

charm_url = switch or charm_url_origin_result.url
parsed_url = URL.parse(charm_url)
charm_name = parsed_url.name

Expand Down Expand Up @@ -810,8 +810,9 @@ async def local_refresh(
"""
app_facade = self._facade()

if not isinstance(path, pathlib.Path):
path = pathlib.Path(path)
if isinstance(path, str) and path.startswith("local:"):
path = path[6:]
path = Path(path)
charm_dir = path.expanduser().resolve()
model_config = await self.get_config()

Expand Down
12 changes: 12 additions & 0 deletions tests/integration/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,18 @@ async def test_upgrade_charm_resource_same_rev_no_update(event_loop):
ress2 = await app.get_resources()
assert ress['policyd-override'].fingerprint == ress2['policyd-override'].fingerprint

@base.bootstrapped
@pytest.mark.asyncio
async def test_refresh_charmhub_to_local(event_loop):
charm_path = INTEGRATION_TEST_DIR / 'charm'
async with base.CleanModel() as model:
app = await model.deploy('ubuntu', application_name='ubu-path')
await app.refresh(path=str(charm_path))
assert app.data['charm-url'].startswith('local:')

app = await model.deploy('ubuntu', application_name='ubu-switch')
await app.refresh(switch=str(charm_path))
assert app.data['charm-url'].startswith('local:')

@base.bootstrapped
@pytest.mark.asyncio
Expand Down

0 comments on commit ef085c3

Please sign in to comment.