mirror of
https://github.com/natelandau/obsidian-metadata.git
synced 2025-11-08 05:03:47 -05:00
fix: improve TOML error handing and docs for Windows paths (#31)
* fix: improve TOML error handing and documentation for Windows paths * build(linting): pash ruff v2.0.260
This commit is contained in:
@@ -61,7 +61,7 @@ repos:
|
||||
entry: yamllint --strict --config-file .yamllint.yml
|
||||
|
||||
- repo: "https://github.com/charliermarsh/ruff-pre-commit"
|
||||
rev: "v0.0.259"
|
||||
rev: "v0.0.260"
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: ["--extend-ignore", "I001,D301,D401"]
|
||||
|
||||
@@ -122,6 +122,8 @@ Below is an example with two vaults.
|
||||
["Vault One"] # Name of the vault.
|
||||
|
||||
# Path to your obsidian vault
|
||||
# Note for Windows users: Windows paths must use `\\` as the path separator due to a limitation with how TOML parses strings.
|
||||
# Example: "C:\\Users\\username\\Documents\\Obsidian"
|
||||
path = "/path/to/vault"
|
||||
|
||||
# Folders within the vault to ignore when indexing metadata
|
||||
@@ -141,6 +143,10 @@ Below is an example with two vaults.
|
||||
|
||||
To bypass the configuration file and specify a vault to use at runtime use the `--vault-path` option.
|
||||
|
||||
**Note for Windows users:**
|
||||
Due to how TOMML parses strings, Windows paths must use `\\` as the path separator.
|
||||
For example: `C:\\Users\\username\\Documents\\Obsidian`
|
||||
|
||||
### Make Bulk Updates
|
||||
|
||||
Bulk edits are supported by importing a CSV file containing the following columns. Column headers must be lowercase.
|
||||
|
||||
38
poetry.lock
generated
38
poetry.lock
generated
@@ -1059,29 +1059,29 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.259"
|
||||
version = "0.0.260"
|
||||
description = "An extremely fast Python linter, written in Rust."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.0.259-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:f3938dc45e2a3f818e9cbd53007265c22246fbfded8837b2c563bf0ebde1a226"},
|
||||
{file = "ruff-0.0.259-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:22e1e35bf5f12072cd644d22afd9203641ccf258bc14ff91aa1c43dc14f6047d"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2fb20e89e85d147c85caa807707a1488bccc1f3854dc3d53533e89b52a0c5ff"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:49e903bcda19f6bb0725a962c058eb5d61f40d84ef52ed53b61939b69402ab4e"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71f0ef1985e9a6696fa97da8459917fa34bdaa2c16bd33bd5edead585b7d44f7"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7cfef26619cba184d59aa7fa17b48af5891d51fc0b755a9bc533478a10d4d066"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79b02fa17ec1fd8d306ae302cb47fb614b71e1f539997858243769bcbe78c6d9"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:428507fb321b386dda70d66cd1a8aa0abf51d7c197983d83bb9e4fa5ee60300b"},
|
||||
{file = "ruff-0.0.259-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5fbaea9167f1852757f02133e5daacdb8c75b3431343205395da5b10499927a"},
|
||||
{file = "ruff-0.0.259-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:40ae87f2638484b7e8a7567b04a7af719f1c484c5bf132038b702bb32e1f6577"},
|
||||
{file = "ruff-0.0.259-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:29e2b77b7d5da6a7dd5cf9b738b511355c5734ece56f78e500d4b5bffd58c1a0"},
|
||||
{file = "ruff-0.0.259-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b3c1beacf6037e7f0781d4699d9a2dd4ba2462f475be5b1f45cf84c4ba3c69d"},
|
||||
{file = "ruff-0.0.259-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:daaea322e7e85f4c13d82be9536309e1c4b8b9851bb0cbc7eeb15d490fd46bf9"},
|
||||
{file = "ruff-0.0.259-py3-none-win32.whl", hash = "sha256:38704f151323aa5858370a2f792e122cc25e5d1aabe7d42ceeab83da18f0b456"},
|
||||
{file = "ruff-0.0.259-py3-none-win_amd64.whl", hash = "sha256:aa9449b898287e621942cc71b9327eceb8f0c357e4065fecefb707ef2d978df8"},
|
||||
{file = "ruff-0.0.259-py3-none-win_arm64.whl", hash = "sha256:e4f39e18702de69faaaee3969934b92d7467285627f99a5b6ecd55a7d9f5d086"},
|
||||
{file = "ruff-0.0.259.tar.gz", hash = "sha256:8b56496063ab3bfdf72339a5fbebb8bd46e5c5fee25ef11a9f03b208fa0562ec"},
|
||||
{file = "ruff-0.0.260-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:c559650b623f3fbdc39c7ed1bcb064765c666a53ee738c53d1461afbf3f23db2"},
|
||||
{file = "ruff-0.0.260-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:90ff1479e292a84c388a8a035d223247ddeea5f6760752a9142b88b6d59ac334"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25584d1b9f445fde72651caab97e7430a4c5bfd2a0ce9af39868753826cba10d"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8032e35357384a29791c75194a71e314031171eb0731fcaa872dfaf4c1f4470a"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e4fa7293f97c021825b3b72f2bf53f0eb4f59625608a889678c1fc6660f412d"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8bec0271e2c8cd36bcf915cb9f6a93e40797a3ff3d2cda4ca87b7bed9e598472"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e075a61aaff8ebe56172217f0ac14c5df9637b289bf161ac697445a9003d5c2"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f8678f54eb2696481618902a10c3cb28325f3323799af99997ad6f06005ea4f5"},
|
||||
{file = "ruff-0.0.260-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57d9f0bfdef739b76aa3112b9182a214f0f34589a2659f88353492c7670fe2fe"},
|
||||
{file = "ruff-0.0.260-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ec1f77219ba5adaa194289cb82ba924ff2ed931fd00b8541d66a1724c89fbc9"},
|
||||
{file = "ruff-0.0.260-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:aae2170a7ec6f7fc4a73db30aa7aa7fce936176bf66bf85f77f69ddd1dd4a665"},
|
||||
{file = "ruff-0.0.260-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f847b72ef994ab88e9da250c7eb5cbb3f1555b92a9f22c5ed1c27a44b7e98d6"},
|
||||
{file = "ruff-0.0.260-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6dd705d4eff405c2b70513188fbff520f49db6df91f0d5e8258c5d469efa58bc"},
|
||||
{file = "ruff-0.0.260-py3-none-win32.whl", hash = "sha256:3866a96b2ef92c7d837ba6bf8fc9dd125a67886f1c5512ad6fa5d5fefaceff87"},
|
||||
{file = "ruff-0.0.260-py3-none-win_amd64.whl", hash = "sha256:0733d524946decbd4f1e63f7dc26820f5c1e6c31da529ba20fb995057f8e79b1"},
|
||||
{file = "ruff-0.0.260-py3-none-win_arm64.whl", hash = "sha256:12542a26f189a5a10c719bfa14d415d0511ac05e5c9ff5e79cc9d5cc50b81bc8"},
|
||||
{file = "ruff-0.0.260.tar.gz", hash = "sha256:ea8f94262f33b81c47ee9d81f455b144e94776f5c925748cb0c561a12206eae1"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1321,4 +1321,4 @@ dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "4eb179bbb559eb12dd73f673a8e7f80706386c88f5d777d5de4ca9b7612ace60"
|
||||
content-hash = "61ab3ff1aa55c93eeec465752dcc92de12fc1c02206184913b67db1c590d3ed8"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
pdoc = "^13.0.1"
|
||||
poethepoet = "^0.19.0"
|
||||
pre-commit = "^3.2.1"
|
||||
ruff = "^0.0.259"
|
||||
ruff = "^0.0.260"
|
||||
sh = "2.0.3"
|
||||
typeguard = "^3.0.2"
|
||||
types-python-dateutil = "^2.8.19.11"
|
||||
|
||||
@@ -77,10 +77,11 @@ class Config:
|
||||
VaultConfig(vault_name=key, vault_config=self.config[key]) for key in self.config
|
||||
]
|
||||
except TypeError as e:
|
||||
log.error(f"Configuration file is invalid: '{self.config_path}'")
|
||||
log.error(f"Configuration file is invalid: '{self.config_path}'\n{e}")
|
||||
raise typer.Exit(code=1) from e
|
||||
|
||||
log.debug(f"Loaded configuration from '{self.config_path}'")
|
||||
log.trace("Configuration:")
|
||||
log.trace(self.config)
|
||||
|
||||
def __rich_repr__(self) -> rich.repr.Result: # pragma: no cover
|
||||
@@ -91,10 +92,10 @@ class Config:
|
||||
def _load_config(self) -> dict[str, Any]:
|
||||
"""Load the configuration file."""
|
||||
try:
|
||||
with self.config_path.open(encoding="utf-8") as fp:
|
||||
with self.config_path.open(mode="rt", encoding="utf-8") as fp:
|
||||
return tomlkit.load(fp)
|
||||
except tomlkit.exceptions.TOMLKitError as e:
|
||||
alerts.error(f"Could not parse '{self.config_path}'")
|
||||
alerts.error(f"Could not parse '{self.config_path}'\n{e}")
|
||||
raise typer.Exit(code=1) from e
|
||||
|
||||
def _validate_config_path(self, config_path: Path | None) -> Path:
|
||||
@@ -117,6 +118,8 @@ class Config:
|
||||
["Vault 1"] # Name of the vault.
|
||||
|
||||
# Path to your obsidian vault
|
||||
# Note for Windows users: Windows paths must use `\\` as the path separator due to a limitation with how TOML parses strings.
|
||||
# Example: "C:\\Users\\username\\Documents\\Obsidian"
|
||||
path = "{vault_path}"
|
||||
|
||||
# Folders within the vault to ignore when indexing metadata
|
||||
|
||||
@@ -282,7 +282,9 @@ def remove_markdown_sections(
|
||||
return text
|
||||
|
||||
|
||||
def validate_csv_bulk_imports(csv_path: Path, note_paths: list) -> dict[str, list[dict[str, str]]]:
|
||||
def validate_csv_bulk_imports( # noqa: C901
|
||||
csv_path: Path, note_paths: list
|
||||
) -> dict[str, list[dict[str, str]]]:
|
||||
"""Validate the bulk import CSV file.
|
||||
|
||||
Args:
|
||||
|
||||
@@ -319,7 +319,7 @@ class Vault:
|
||||
|
||||
return num_changed
|
||||
|
||||
def export_metadata(self, path: str, export_format: str = "csv") -> None:
|
||||
def export_metadata(self, path: str, export_format: str = "csv") -> None: # noqa: C901
|
||||
"""Write metadata to a csv file.
|
||||
|
||||
Args:
|
||||
@@ -333,7 +333,7 @@ class Vault:
|
||||
|
||||
match export_format:
|
||||
case "csv":
|
||||
with export_file.open(mode="w", encoding="UTF8") as f:
|
||||
with export_file.open(mode="w", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["Metadata Type", "Key", "Value"])
|
||||
|
||||
@@ -361,7 +361,7 @@ class Vault:
|
||||
"tags": self.metadata.tags,
|
||||
}
|
||||
|
||||
with export_file.open(mode="w", encoding="UTF8") as f:
|
||||
with export_file.open(mode="w", encoding="utf-8") as f:
|
||||
json.dump(dict_to_dump, f, indent=4, ensure_ascii=False, sort_keys=True)
|
||||
|
||||
def export_notes_to_csv(self, path: str) -> None:
|
||||
@@ -375,7 +375,7 @@ class Vault:
|
||||
alerts.error(f"Path does not exist: {export_file.parent}")
|
||||
raise typer.Exit(code=1)
|
||||
|
||||
with export_file.open(mode="w", encoding="UTF8") as f:
|
||||
with export_file.open(mode="w", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["path", "type", "key", "value"])
|
||||
|
||||
|
||||
@@ -103,6 +103,8 @@ def test_no_config_no_vault(tmp_path, mocker) -> None:
|
||||
["Vault 1"] # Name of the vault.
|
||||
|
||||
# Path to your obsidian vault
|
||||
# Note for Windows users: Windows paths must use `\\` as the path separator due to a limitation with how TOML parses strings.
|
||||
# Example: "C:\\Users\\username\\Documents\\Obsidian"
|
||||
path = "{str(fake_vault)}"
|
||||
|
||||
# Folders within the vault to ignore when indexing metadata
|
||||
|
||||
Reference in New Issue
Block a user