Skip to content

Commit

Permalink
charmcraft/jujuignore.py: Allow extending the list of patterns. (#99)
Browse files Browse the repository at this point in the history
This adds the ability for JujuIgnore to pull in the default ignores and extend them with .jujuignore contents.

I don't have tests around the walk functionality, but I figured I would leave it in there to show you how I was thinking it would look.
  • Loading branch information
jameinel committed Aug 13, 2020
2 parents 1b64b1c + e803844 commit b9c265a
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
11 changes: 11 additions & 0 deletions charmcraft/commands/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import yaml

from charmcraft.cmdbase import BaseCommand, CommandError
from charmcraft.jujuignore import JujuIgnore, default_juju_ignore
from .utils import make_executable

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -87,6 +88,7 @@ def __init__(self, args):
self.requirement_paths = args['requirement']

self.buildpath = self.charmdir / BUILD_DIRNAME
self.ignore_rules = self._load_juju_ignore()

def run(self):
"""Main building process."""
Expand All @@ -110,11 +112,20 @@ def _link_to_buildpath(self, srcpath):
destpath.symlink_to(srcpath)
return destpath

def _load_juju_ignore(self):
ignore = JujuIgnore(default_juju_ignore)
path = self.charmdir / '.jujuignore'
if path.exists():
with path.open('r', encoding='utf-8') as ignores:
ignore.extend_patterns(ignores)
return ignore

def handle_code(self):
"""Handle basic files and the charm source code."""
# basic files
logger.debug("Linking in basic files and charm code")
self._link_to_buildpath(self.charmdir / CHARM_METADATA)

for fn in CHARM_OPTIONAL:
path = self.charmdir / fn
if path.exists():
Expand Down
6 changes: 5 additions & 1 deletion charmcraft/jujuignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,11 @@ def __init__(self, patterns: typing.Iterable[str]):
self._matchers = []
self._compile_from(patterns)

def _compile_from(self, patterns):
def extend_patterns(self, patterns: typing.Iterable[str]) -> None:
"""Add more patterns to the ignore list."""
self._compile_from(patterns)

def _compile_from(self, patterns: typing.Iterable[str]):
for line_num, rule in enumerate(patterns, 1):
orig_rule = rule
rule = rule.lstrip().rstrip('\r\n')
Expand Down
40 changes: 40 additions & 0 deletions tests/commands/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,3 +894,43 @@ def test_build_package_name(tmp_path, monkeypatch):
zipname = builder.handle_package()

assert zipname == "name-from-metadata.charm"


def test_builder_without_jujuignore(tmp_path):
"""Without a .jujuignore we still have a default set of ignores"""
build_dir = tmp_path / BUILD_DIRNAME
build_dir.mkdir()

builder = Builder({
'from': tmp_path,
'entrypoint': 'whatever',
'requirement': [],
})
ignore = builder._load_juju_ignore()
assert ignore.match('/.git', is_dir=True)
assert ignore.match('/build', is_dir=True)
assert not ignore.match('myfile.py', is_dir=False)


def test_builder_with_jujuignore(tmp_path):
"""With a .jujuignore we will include additional ignores."""
build_dir = tmp_path / BUILD_DIRNAME
build_dir.mkdir()
with (tmp_path / '.jujuignore').open('w', encoding='utf-8') as ignores:
ignores.write(
'*.py\n'
'/h\xef.txt\n'
)

builder = Builder({
'from': tmp_path,
'entrypoint': 'whatever',
'requirement': [],
})
ignore = builder._load_juju_ignore()
assert ignore.match('/.git', is_dir=True)
assert ignore.match('/build', is_dir=True)
assert ignore.match('myfile.py', is_dir=False)
assert not ignore.match('hi.txt', is_dir=False)
assert ignore.match('h\xef.txt', is_dir=False)
assert not ignore.match('myfile.c', is_dir=False)
9 changes: 9 additions & 0 deletions tests/test_jujuignore.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,3 +397,12 @@ def test_special_chars_in_brackets():
['foob.py', 'fooc.py', 'foo^.py'],
[r'foo.py', r'fooa.py', r'fooa^.py'],
)


def test_extend_patterns():
ignore = jujuignore.JujuIgnore(['foo'])
assert ignore.match('foo', is_dir=False)
assert not ignore.match('bar', is_dir=False)
ignore.extend_patterns(['bar'])
assert ignore.match('foo', is_dir=False)
assert ignore.match('bar', is_dir=False)

0 comments on commit b9c265a

Please sign in to comment.