-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathhatch_build.py
More file actions
157 lines (132 loc) · 7.02 KB
/
hatch_build.py
File metadata and controls
157 lines (132 loc) · 7.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""Custom build hook to copy examples to resources during package build."""
import shutil
import tomllib
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class CustomBuildHook(BuildHookInterface):
"""Custom build hook to copy examples to resources structure."""
def initialize(self, version: str, build_data: dict[str, Any]) -> None:
"""Copy examples from root to resources structure."""
# Clear existing resources/examples directory for clean build
resources_examples_dir = Path(self.root) / "src/fast_agent/resources/examples"
if resources_examples_dir.exists():
shutil.rmtree(resources_examples_dir)
print("fast-agent build: Cleared existing resources/examples directory")
# Clear existing fast_agent setup resources for clean build
resources_setup_dir = Path(self.root) / "src/fast_agent/resources/setup"
if resources_setup_dir.exists():
shutil.rmtree(resources_setup_dir)
print("fast-agent build: Cleared existing resources/setup directory")
# Clear existing internal shared resources for clean build
resources_shared_dir = Path(self.root) / "src/fast_agent/resources/shared"
if resources_shared_dir.exists():
shutil.rmtree(resources_shared_dir)
print("fast-agent build: Cleared existing resources/shared directory")
# Define source to target mappings
# Examples:
# examples/workflows -> src/fast_agent/resources/examples/workflows
# examples/mcp/elicitations -> src/fast_agent/resources/examples/mcp/elicitations
EXAMPLES_DIR = Path("src") / "fast_agent" / "resources" / "examples"
example_mappings = {
"examples/workflows": EXAMPLES_DIR / "workflows",
"examples/researcher": EXAMPLES_DIR / "researcher",
"examples/data-analysis": EXAMPLES_DIR / "data-analysis",
"examples/mcp/state-transfer": EXAMPLES_DIR / "mcp" / "state-transfer",
"examples/mcp/elicitations": EXAMPLES_DIR / "mcp" / "elicitations",
"examples/tensorzero": EXAMPLES_DIR / "tensorzero",
"examples/hf-toad-cards": EXAMPLES_DIR / "hf-toad-cards",
}
# Define setup template mapping (editable templates -> packaged resources)
setup_mappings = {
# examples/setup -> src/fast_agent/resources/setup
"examples/setup": "src/fast_agent/resources/setup",
}
# Define internal shared resource mapping
shared_mappings = {
# resources/shared -> src/fast_agent/resources/shared
"resources/shared": "src/fast_agent/resources/shared",
}
print("fast-agent build: Copying examples to resources...")
for source_path, target_path in example_mappings.items():
source_dir = Path(self.root) / source_path
target_dir = Path(self.root) / target_path
if source_dir.exists():
# Ensure target directory exists
target_dir.parent.mkdir(parents=True, exist_ok=True)
# Copy the entire directory tree
shutil.copytree(source_dir, target_dir)
print(f" Copied {source_path} -> {target_path}")
else:
print(f" Warning: Source directory not found: {source_path}")
print("Fast-agent build: Example copying completed.")
# Copy setup templates
print("fast-agent build: Copying setup templates to resources...")
for source_path, target_path in setup_mappings.items():
source_dir = Path(self.root) / source_path
target_dir = Path(self.root) / target_path
if source_dir.exists():
target_dir.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(source_dir, target_dir)
print(f" Copied {source_path} -> {target_path}")
else:
print(f" Warning: Setup templates directory not found: {source_path}")
print("fast-agent build: Copying shared internal resources...")
for source_path, target_path in shared_mappings.items():
source_dir = Path(self.root) / source_path
target_dir = Path(self.root) / target_path
if source_dir.exists():
target_dir.parent.mkdir(parents=True, exist_ok=True)
shutil.copytree(source_dir, target_dir)
print(f" Copied {source_path} -> {target_path}")
else:
print(f" Warning: Shared resources directory not found: {source_path}")
# Generate manifest.txt with build metadata
print("Fast-agent build: Generating manifest.txt...")
package_version = self._get_package_version()
manifest_content = self._generate_manifest(package_version)
manifest_path = Path(self.root) / "src/fast_agent/resources/manifest.txt"
manifest_path.parent.mkdir(parents=True, exist_ok=True)
manifest_path.write_text(manifest_content)
print(f" Created manifest.txt (version={package_version})")
# Ensure the copied files are included in the build
if "artifacts" not in build_data:
build_data["artifacts"] = []
# Add all copied files as artifacts
for target_path in (
list(example_mappings.values())
+ list(setup_mappings.values())
+ list(shared_mappings.values())
):
target_dir = Path(self.root) / target_path
if target_dir.exists():
# Add all files in the target directory recursively
for file_path in target_dir.rglob("*"):
if file_path.is_file():
relative_path = str(file_path.relative_to(Path(self.root)))
if relative_path not in build_data["artifacts"]:
build_data["artifacts"].append(relative_path)
print(f" Added artifact: {relative_path}")
# Add manifest.txt as an artifact
manifest_relative = "src/fast_agent/resources/manifest.txt"
if manifest_relative not in build_data["artifacts"]:
build_data["artifacts"].append(manifest_relative)
print(f" Added artifact: {manifest_relative}")
def _get_package_version(self) -> str:
"""Read the package version from pyproject.toml."""
pyproject_path = Path(self.root) / "pyproject.toml"
try:
with open(pyproject_path, "rb") as f:
pyproject = tomllib.load(f)
return pyproject.get("project", {}).get("version", "unknown")
except Exception:
return "unknown"
def _generate_manifest(self, version: str) -> str:
"""Generate manifest.txt content with build metadata."""
build_timestamp = datetime.now(timezone.utc).isoformat()
return f"""# fast-agent-mcp build manifest
package_name=fast-agent-mcp
version={version}
build_timestamp={build_timestamp}
"""