chipfoundry-cli 2.5.3__tar.gz → 2.5.4__tar.gz
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.
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/PKG-INFO +1 -1
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/__init__.py +1 -1
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/main.py +55 -18
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/pyproject.toml +1 -1
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/LICENSE +0 -0
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/README.md +0 -0
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/check_refs.py +0 -0
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/remote_precheck_git.py +0 -0
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/utils.py +0 -0
- {chipfoundry_cli-2.5.3 → chipfoundry_cli-2.5.4}/chipfoundry_cli/version_check.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""ChipFoundry CLI package: Automate project submission to SFTP."""
|
|
2
|
-
__version__ = "2.5.
|
|
2
|
+
__version__ = "2.5.4"
|
|
@@ -1735,6 +1735,39 @@ def _sha256_file(path: Path) -> str:
|
|
|
1735
1735
|
return h.hexdigest()
|
|
1736
1736
|
|
|
1737
1737
|
|
|
1738
|
+
def _ordered_sftp_uploads(upload_map: dict) -> list:
|
|
1739
|
+
"""Return payload files first and project.json last as the commit marker."""
|
|
1740
|
+
config_path = upload_map.get(".cf/project.json")
|
|
1741
|
+
if not config_path:
|
|
1742
|
+
raise ValueError("SFTP push requires .cf/project.json")
|
|
1743
|
+
payloads = [
|
|
1744
|
+
(rel_path, local_path)
|
|
1745
|
+
for rel_path, local_path in upload_map.items()
|
|
1746
|
+
if rel_path != ".cf/project.json" and local_path
|
|
1747
|
+
]
|
|
1748
|
+
payloads.append((".cf/project.json", config_path))
|
|
1749
|
+
return payloads
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
def _prepared_wrapper_hash(project_json_path: str) -> str:
|
|
1753
|
+
with open(project_json_path, "r") as f:
|
|
1754
|
+
data = json.load(f)
|
|
1755
|
+
value = str((data.get("project") or {}).get("user_project_wrapper_hash") or "").strip()
|
|
1756
|
+
if not value:
|
|
1757
|
+
raise ValueError("project.json is missing project.user_project_wrapper_hash")
|
|
1758
|
+
return value
|
|
1759
|
+
|
|
1760
|
+
|
|
1761
|
+
def _assert_wrapper_hash_unchanged(wrapper_path: str, expected_hash: str) -> None:
|
|
1762
|
+
current_hash = _sha256_file(Path(wrapper_path))
|
|
1763
|
+
if current_hash != expected_hash:
|
|
1764
|
+
raise RuntimeError(
|
|
1765
|
+
"Wrapper GDS changed while it was being uploaded. "
|
|
1766
|
+
"project.json was not uploaded; stop any process modifying the GDS "
|
|
1767
|
+
"and run cf push --force-overwrite again."
|
|
1768
|
+
)
|
|
1769
|
+
|
|
1770
|
+
|
|
1738
1771
|
def _collect_push_candidates(project_root: Path) -> List[Tuple[str, Path, int, str]]:
|
|
1739
1772
|
"""Return [(rel_path, abs_path, size, kind)] for files the platform
|
|
1740
1773
|
accepts via --https.
|
|
@@ -2111,17 +2144,22 @@ def push(project_root, sftp_host, sftp_username, sftp_key, project_id, project_n
|
|
|
2111
2144
|
cf_dir = ensure_cf_directory(project_root)
|
|
2112
2145
|
|
|
2113
2146
|
# Find the GDS file path for hash calculation
|
|
2114
|
-
|
|
2115
|
-
for gds_key,
|
|
2147
|
+
wrapper_path = None
|
|
2148
|
+
for gds_key, local_path in collected.items():
|
|
2116
2149
|
if gds_key.startswith("gds/"):
|
|
2150
|
+
wrapper_path = local_path
|
|
2117
2151
|
break
|
|
2152
|
+
if not wrapper_path:
|
|
2153
|
+
console.print("[red]No wrapper GDS found in collected project files.[/red]")
|
|
2154
|
+
raise click.Abort()
|
|
2118
2155
|
|
|
2119
2156
|
project_json_path = update_or_create_project_json(
|
|
2120
2157
|
cf_dir=str(cf_dir),
|
|
2121
|
-
gds_path=
|
|
2158
|
+
gds_path=wrapper_path,
|
|
2122
2159
|
cli_overrides=cli_overrides,
|
|
2123
2160
|
existing_json_path=collected.get(".cf/project.json")
|
|
2124
2161
|
)
|
|
2162
|
+
prepared_wrapper_hash = _prepared_wrapper_hash(project_json_path)
|
|
2125
2163
|
|
|
2126
2164
|
# SFTP upload or dry-run
|
|
2127
2165
|
final_project_name = project_name or (
|
|
@@ -2135,16 +2173,14 @@ def push(project_root, sftp_host, sftp_username, sftp_key, project_id, project_n
|
|
|
2135
2173
|
upload_map["verilog/rtl/user_defines.v"] = collected.get("verilog/rtl/user_defines.v")
|
|
2136
2174
|
|
|
2137
2175
|
# Add the appropriate GDS file based on what was collected
|
|
2138
|
-
for gds_key,
|
|
2176
|
+
for gds_key, local_path in collected.items():
|
|
2139
2177
|
if gds_key.startswith("gds/"):
|
|
2140
|
-
upload_map[gds_key] =
|
|
2178
|
+
upload_map[gds_key] = local_path
|
|
2141
2179
|
|
|
2142
2180
|
if dry_run:
|
|
2143
2181
|
console.print("[bold]Files to upload:[/bold]")
|
|
2144
|
-
for rel_path, local_path in upload_map
|
|
2145
|
-
|
|
2146
|
-
remote_path = os.path.join(sftp_base, rel_path)
|
|
2147
|
-
console.print(f" {os.path.basename(local_path)} → {rel_path}")
|
|
2182
|
+
for rel_path, local_path in _ordered_sftp_uploads(upload_map):
|
|
2183
|
+
console.print(f" {os.path.basename(local_path)} → {rel_path}")
|
|
2148
2184
|
return
|
|
2149
2185
|
|
|
2150
2186
|
console.print(f"Connecting to {sftp_host}...")
|
|
@@ -2163,15 +2199,16 @@ def push(project_root, sftp_host, sftp_username, sftp_key, project_id, project_n
|
|
|
2163
2199
|
raise click.Abort()
|
|
2164
2200
|
|
|
2165
2201
|
try:
|
|
2166
|
-
for rel_path, local_path in upload_map
|
|
2167
|
-
if
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2202
|
+
for rel_path, local_path in _ordered_sftp_uploads(upload_map):
|
|
2203
|
+
if rel_path == ".cf/project.json":
|
|
2204
|
+
_assert_wrapper_hash_unchanged(wrapper_path, prepared_wrapper_hash)
|
|
2205
|
+
remote_path = os.path.join(sftp_base, rel_path)
|
|
2206
|
+
upload_with_progress(
|
|
2207
|
+
sftp,
|
|
2208
|
+
local_path=local_path,
|
|
2209
|
+
remote_path=remote_path,
|
|
2210
|
+
force_overwrite=force_overwrite
|
|
2211
|
+
)
|
|
2175
2212
|
console.print(f"[green]✓ Uploaded to {sftp_base}[/green]")
|
|
2176
2213
|
|
|
2177
2214
|
except Exception as e:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|