Git Intake - Bring projects into the Drydock
Streamlined tool for cloning/linking projects into Ship_Yard/_intake/
with automatic analysis setup.
Usage
python git_intake.py [options]
python git_intake.py https://github.com/microsoft/vscode --shallow
python git_intake.py /local/path/to/project --link
python git_intake.py https://github.com/org/repo --branch develop --analyze
Examples:
Clone from GitHub (shallow)
python git_intake.py https://github.com/microsoft/vscode --shallow
Link local project (symlink, no copy)
python git_intake.py /path/to/local/project --link
Clone specific branch and auto-analyze
python git_intake.py https://github.com/org/repo --branch main --analyze
Clone specific tag
python git_intake.py https://github.com/org/repo --tag v1.0.0
Functions
extract_project_name(source: str) -> str
Extract project name from URL or path.
Source code in Tools/intake/git_intake.py
| def extract_project_name(source: str) -> str:
"""Extract project name from URL or path."""
# Handle Git URLs
if source.startswith(('http://', 'https://', 'git@')):
# Remove .git suffix
name = source.rstrip('/').rstrip('.git').split('/')[-1]
return name
# Handle local paths
path = Path(source)
return path.name
|
extract_org_name(source: str) -> str
Extract organization/user name from URL.
Source code in Tools/intake/git_intake.py
| def extract_org_name(source: str) -> str:
"""Extract organization/user name from URL."""
if source.startswith(('http://', 'https://')):
parts = urlparse(source).path.strip('/').split('/')
if len(parts) >= 2:
return parts[0]
elif source.startswith('git@'):
# git@github.com:org/repo.git
match = re.search(r':([^/]+)/', source)
if match:
return match.group(1)
return "unknown"
|
clone_repo
clone_repo(url: str, target_path: Path, branch: str = None, tag: str = None, shallow: bool = False, depth: int = 1) -> bool
Clone a git repository.
Source code in Tools/intake/git_intake.py
| def clone_repo(
url: str,
target_path: Path,
branch: str = None,
tag: str = None,
shallow: bool = False,
depth: int = 1
) -> bool:
"""Clone a git repository."""
cmd = ["git", "clone"]
if shallow:
cmd.extend(["--depth", str(depth)])
if branch:
cmd.extend(["--branch", branch])
elif tag:
cmd.extend(["--branch", tag])
cmd.extend([url, str(target_path)])
print(f"Cloning: {url}")
print(f"Target: {target_path}")
if branch:
print(f"Branch: {branch}")
if tag:
print(f"Tag: {tag}")
if shallow:
print(f"Shallow: depth={depth}")
print()
result = subprocess.run(cmd, capture_output=False)
return result.returncode == 0
|
link_local
link_local(source: Path, target_path: Path) -> bool
Create symlink to local project.
Source code in Tools/intake/git_intake.py
| def link_local(source: Path, target_path: Path) -> bool:
"""Create symlink to local project."""
source = source.resolve()
if not source.exists():
print(f"Error: Source path does not exist: {source}")
return False
if not source.is_dir():
print(f"Error: Source is not a directory: {source}")
return False
print(f"Linking: {source}")
print(f"Target: {target_path}")
try:
target_path.symlink_to(source)
return True
except OSError as e:
print(f"Error creating symlink: {e}")
return False
|
get_git_info
get_git_info(repo_path: Path) -> dict
Get git information from a repository.
Source code in Tools/intake/git_intake.py
| def get_git_info(repo_path: Path) -> dict:
"""Get git information from a repository."""
info = {
"commit": None,
"branch": None,
"remote": None,
"tags": [],
}
try:
# Get current commit
result = subprocess.run(
["git", "rev-parse", "HEAD"],
cwd=repo_path,
capture_output=True,
text=True
)
if result.returncode == 0:
info["commit"] = result.stdout.strip()[:12]
# Get current branch
result = subprocess.run(
["git", "branch", "--show-current"],
cwd=repo_path,
capture_output=True,
text=True
)
if result.returncode == 0:
info["branch"] = result.stdout.strip() or "detached"
# Get remote URL
result = subprocess.run(
["git", "remote", "get-url", "origin"],
cwd=repo_path,
capture_output=True,
text=True
)
if result.returncode == 0:
info["remote"] = result.stdout.strip()
# Get tags pointing to current commit
result = subprocess.run(
["git", "tag", "--points-at", "HEAD"],
cwd=repo_path,
capture_output=True,
text=True
)
if result.returncode == 0 and result.stdout.strip():
info["tags"] = result.stdout.strip().split('\n')
except Exception:
pass
return info
|
create_analysis_folder
create_analysis_folder(project_name: str, source: str, git_info: dict) -> Path
Create analysis folder structure for the project.
Source code in Tools/intake/git_intake.py
| def create_analysis_folder(project_name: str, source: str, git_info: dict) -> Path:
"""Create analysis folder structure for the project."""
analysis_path = ANALYSIS_DIR / project_name
components_path = analysis_path / "components"
analysis_path.mkdir(parents=True, exist_ok=True)
components_path.mkdir(exist_ok=True)
# Create intake record
intake_record = f"""# Intake Record: {project_name}
## Source
| Field | Value |
|-------|-------|
| Source | `{source}` |
| Intake Date | {datetime.now().strftime('%Y-%m-%d %H:%M')} |
| Commit | `{git_info.get('commit', 'N/A')}` |
| Branch | `{git_info.get('branch', 'N/A')}` |
| Tags | {', '.join(git_info.get('tags', [])) or 'None'} |
## Status
- [ ] Structure analyzed
- [ ] Dependencies mapped
- [ ] Architecture documented
- [ ] Components identified
- [ ] Extraction plan created
## Notes
{{Add notes about this project}}
---
*Intake by: Drydock git_intake.py*
"""
(analysis_path / "intake-record.md").write_text(intake_record)
return analysis_path
|
run_analyzers
run_analyzers(project_path: Path, analysis_path: Path) -> None
Run standard analyzers on the project.
Source code in Tools/intake/git_intake.py
| def run_analyzers(project_path: Path, analysis_path: Path) -> None:
"""Run standard analyzers on the project."""
analyzers = [
("structure_analyzer.py", "structure.md"),
("platform_detector.py", "platforms.md"),
("dependency_analyzer.py", "dependencies.md"),
]
print("\nRunning analyzers...")
for analyzer, output_file in analyzers:
analyzer_path = TOOLS_DIR / "analyzers" / analyzer
if not analyzer_path.exists():
print(f" Skipping {analyzer} (not found)")
continue
output_path = analysis_path / output_file
print(f" Running {analyzer}...")
result = subprocess.run(
["python3", str(analyzer_path), str(project_path), "-o", str(output_path)],
capture_output=True,
text=True
)
if result.returncode == 0:
print(f" → {output_file}")
else:
print(f" → Failed: {result.stderr[:100]}")
|