Skip to content

Commit

Permalink
add config file
Browse files Browse the repository at this point in the history
  • Loading branch information
luto committed Jul 11, 2024
1 parent a758df8 commit ea55d6e
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 3 deletions.
24 changes: 23 additions & 1 deletion docs/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,32 @@ PASS % whoami
PASS % pwd
```

## Config File

Shellinspector can be configured within a project using a file called
`shellinspector.yaml` somewhere up the directory tree relative to your `.ispec`
file. Only the first/nearest config file found will be considered. The search is
also stopped, if a `.git` directory is found, assuming this is the project root.

You can use all settings available in Frontmatter here.

```
fixture_dirs:
- fixtures/
include_dirs:
- includes/
settings:
timeout_seconds: 10
```

All given relative paths are relative to the `shellinspector.yaml` file itself.

## Frontmatter

Shellinspector can be configured in various ways outlined below. These config
values are set using an optional YAML section at the start of the file.
values are set using an optional YAML section at the start of the file. This
takes precedence over the values provided in the config file. The `settings`
dict gets merged, all other values are overwritten completely.

```
---
Expand Down
30 changes: 28 additions & 2 deletions src/shellinspector/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,39 @@ def parse_commands(specfile: Specfile, commands: str) -> None:
cmd.expected = cmd.expected.rstrip("\n")


def parse_global_config(ispec_path: str):
search_path = Path(ispec_path)

while str(search_path) != search_path.root:
search_path = Path(search_path).parent

try:
with open(search_path / "shellinspector.yaml") as f:
return yaml.safe_load(f)
except FileNotFoundError:
pass

if (search_path / ".git").exists():
break

return {}


def parse(path: str, stream: typing.IO) -> Specfile:
specfile = Specfile(path)

config = parse_global_config(path)

frontmatter, commands = parse_yaml_multidoc(stream)

specfile.examples = frontmatter.get("examples", [])
specfile.environment = frontmatter.get("environment", {})
# use values in frontmatter if they exist, otherwise use global config
for key in ["examples", "environment"]:
try:
value = frontmatter[key]
except LookupError:
value = config.get(key, None)

setattr(specfile, key, value)

parse_commands(specfile, commands)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
environment:
FROM_CONFIG: 1
examples:
- FROM_CONFIG: 1
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
same_dir: true
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
with_dotgit_1: true
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
with_dotgit_2: true
Empty file.
48 changes: 48 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from shellinspector.parser import Command
from shellinspector.parser import ExecutionMode
from shellinspector.parser import parse
from shellinspector.parser import parse_global_config
from shellinspector.parser import parse_yaml_multidoc


Expand Down Expand Up @@ -489,3 +490,50 @@ def test_command_short_regex():
"$ echo a\nb",
)
assert cmd.short == "USER(None@local) `echo a` (expect 2 lines, REGEX)"


@pytest.mark.parametrize(
"ispec_path,expected_cfg",
[
("with_dotgit_1/tests/some.ispec", {"with_dotgit_1": True}),
("with_dotgit_2/tests/some.ispec", {}),
("same_dir/tests/some.ispec", {"same_dir": True}),
("none/tests/some.ispec", {}),
("/dev/null", {}),
],
)
def test_parse_global_config(ispec_path, expected_cfg):
cfg = parse_global_config(
Path(__file__).parent / "fixtures/parse_global_config" / ispec_path
)

assert cfg == expected_cfg


def test_global_config_combine():
specfile = parse(
Path(__file__).parent / "fixtures/parse_global_config/combine/some.ispec",
make_stream(
[
"---",
"environment:",
" FROM_ISPEC: 1",
"examples:",
" - FROM_ISPEC: 1",
"---",
]
),
)

assert specfile.environment == {"FROM_ISPEC": 1}
assert specfile.examples == [{"FROM_ISPEC": 1}]


def test_global_config_default():
specfile = parse(
Path(__file__).parent / "fixtures/parse_global_config/combine/some.ispec",
make_stream(["---", "---"]),
)

assert specfile.environment == {"FROM_CONFIG": 1}
assert specfile.examples == [{"FROM_CONFIG": 1}]

0 comments on commit ea55d6e

Please sign in to comment.