furu 0.0.4__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
furu/config.py CHANGED
@@ -1,6 +1,10 @@
1
1
  import os
2
2
  from importlib import import_module
3
3
  from pathlib import Path
4
+ from typing import Literal, cast
5
+
6
+
7
+ RecordGitMode = Literal["ignore", "cached", "uncached"]
4
8
 
5
9
 
6
10
  class FuruConfig:
@@ -41,21 +45,14 @@ class FuruConfig:
41
45
  "true",
42
46
  "yes",
43
47
  }
44
- self.ignore_git_diff = os.getenv("FURU_IGNORE_DIFF", "0").lower() in {
45
- "1",
46
- "true",
47
- "yes",
48
- }
49
- self.require_git = os.getenv("FURU_REQUIRE_GIT", "1").lower() in {
50
- "1",
51
- "true",
52
- "yes",
53
- }
54
- self.require_git_remote = os.getenv("FURU_REQUIRE_GIT_REMOTE", "1").lower() in {
55
- "1",
56
- "true",
57
- "yes",
58
- }
48
+ self.record_git = self._parse_record_git(os.getenv("FURU_RECORD_GIT", "cached"))
49
+ self.allow_no_git_origin = self._parse_bool(
50
+ os.getenv("FURU_ALLOW_NO_GIT_ORIGIN", "0")
51
+ )
52
+ if self.allow_no_git_origin and self.record_git == "ignore":
53
+ raise ValueError(
54
+ "FURU_ALLOW_NO_GIT_ORIGIN cannot be enabled when FURU_RECORD_GIT=ignore"
55
+ )
59
56
  always_rerun_items = {
60
57
  item.strip()
61
58
  for item in os.getenv("FURU_ALWAYS_RERUN", "").split(",")
@@ -77,35 +74,25 @@ class FuruConfig:
77
74
  "FURU_CANCELLED_IS_PREEMPTED", "false"
78
75
  ).lower() in {"1", "true", "yes"}
79
76
 
80
- # Parse FURU_CACHE_METADATA: "never", "forever", or duration like "5m", "1h"
81
- # Default: "5m" (5 minutes) - balances performance with freshness
82
- self.cache_metadata_ttl_sec: float | None = self._parse_cache_duration(
83
- os.getenv("FURU_CACHE_METADATA", "5m")
84
- )
85
-
86
77
  @staticmethod
87
- def _parse_cache_duration(value: str) -> float | None:
88
- """Parse cache duration string into seconds. Returns None for 'never', float('inf') for 'forever'."""
89
- value = value.strip().lower()
90
- if value in {"never", "0", "false", "no"}:
91
- return None # No caching
92
- if value in {"forever", "inf", "true", "yes", "1"}:
93
- return float("inf") # Cache forever
94
-
95
- # Parse duration like "5m", "1h", "30s"
96
- import re
97
-
98
- match = re.match(r"^(\d+(?:\.\d+)?)\s*([smh]?)$", value)
99
- if not match:
78
+ def _parse_bool(value: str) -> bool:
79
+ return value.strip().lower() in {"1", "true", "yes"}
80
+
81
+ @classmethod
82
+ def _parse_record_git(cls, value: str) -> RecordGitMode:
83
+ normalized = value.strip().lower()
84
+ allowed = {"ignore", "cached", "uncached"}
85
+ if normalized not in allowed:
100
86
  raise ValueError(
101
- f"Invalid FURU_CACHE_METADATA value: {value!r}. "
102
- "Use 'never', 'forever', or duration like '5m', '1h', '30s'"
87
+ "FURU_RECORD_GIT must be one of 'ignore', 'cached', or 'uncached'"
103
88
  )
89
+ return cast(RecordGitMode, normalized)
104
90
 
105
- num = float(match.group(1))
106
- unit = match.group(2) or "s"
107
- multipliers = {"s": 1, "m": 60, "h": 3600}
108
- return num * multipliers[unit]
91
+ @property
92
+ def cache_metadata_ttl_sec(self) -> float | None:
93
+ if self.record_git == "cached":
94
+ return float("inf")
95
+ return None
109
96
 
110
97
  def get_root(self, version_controlled: bool = False) -> Path:
111
98
  """Get root directory for storage (version_controlled uses its own root)."""