yatfa 1.0.88 → 1.0.90

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.
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Repository cloning and context setup
4
+ # Extracted from setup-agent.rb for modularity
5
+ #
6
+ # Handles git clone, timeout handling, safe.directory configuration,
7
+ # and REPOSITORIES_CONTEXT persistence for shell sessions.
8
+ #
9
+ # Dependencies:
10
+ # - Standard library requires (json, fileutils, timeout, etc.) are loaded
11
+ # by setup-agent.rb before this file is required
12
+
13
+ def clone_repositories!
14
+ return unless ENV["REPOSITORIES_CONFIG"]
15
+
16
+ begin
17
+ repos = JSON.parse(ENV["REPOSITORIES_CONFIG"])
18
+ return unless repos.is_a?(Array) && repos.any?
19
+
20
+ puts "📚 Cloning #{repos.count} repositories..."
21
+
22
+ repos.each do |repo|
23
+ repo_name = repo["name"]
24
+ github_url = repo["github_url"]
25
+ sandbox_path = repo["path_in_sandbox"] || "/workspace/#{repo_name}"
26
+
27
+ # Create parent directory if needed
28
+ parent_dir = File.dirname(sandbox_path)
29
+ FileUtils.mkdir_p(parent_dir) unless File.exist?(parent_dir)
30
+
31
+ # Clone repository if it doesn't exist
32
+ # Do NOT use --depth to allow full branch access for PR workflows
33
+ unless File.exist?(sandbox_path)
34
+ puts " 📥 Cloning #{repo_name} to #{sandbox_path}..."
35
+ clone_timeout = ENV.fetch("GIT_CLONE_TIMEOUT", "180").to_i
36
+ clone_success = begin
37
+ Timeout.timeout(clone_timeout) do
38
+ system("git", "clone", github_url, sandbox_path)
39
+ end
40
+ rescue Timeout::Error
41
+ # Kill orphan git clone subprocess (Timeout.timeout doesn't kill children)
42
+ system("pkill", "-f", "git clone #{github_url}", err: File::NULL)
43
+ # Clean up partial clone directory so restart doesn't skip it
44
+ FileUtils.rm_rf(sandbox_path) if File.exist?(sandbox_path)
45
+ puts "❌ git clone of #{repo_name} timed out after #{clone_timeout}s"
46
+ puts " The container will restart automatically."
47
+ exit 1
48
+ end
49
+
50
+ unless clone_success
51
+ puts "❌ git clone of #{repo_name} failed"
52
+ puts " The container will restart automatically."
53
+ exit 1
54
+ end
55
+ else
56
+ puts " ✓ #{repo_name} already exists at #{sandbox_path}"
57
+ # Fetch all remotes to ensure branches are up to date
58
+ Dir.chdir(sandbox_path) do
59
+ system("git", "fetch", "--all")
60
+ puts " ✓ Fetched all remotes for #{repo_name}"
61
+ end
62
+ end
63
+
64
+ # Add repository path to git safe.directory to avoid "dubious ownership" errors
65
+ system("git", "config", "--global", "--add", "safe.directory", sandbox_path)
66
+ puts " ✓ Added #{sandbox_path} to git safe.directory"
67
+ end
68
+
69
+ puts "✅ Repositories cloned"
70
+
71
+ # Track if we have a single repository for later use
72
+ single_repo_name = repos.count == 1 ? repos.first['name'] : nil
73
+
74
+ # Write repository context to a file for hooks to read
75
+ # This is more reliable than environment variables in tmux sessions
76
+ if ENV["REPOSITORIES_CONTEXT"]
77
+ repo_context_file = File.expand_path("~/.claude/repos_context.txt")
78
+ File.write(repo_context_file, ENV["REPOSITORIES_CONTEXT"])
79
+ puts "📝 Repository context written to #{repo_context_file}"
80
+ end
81
+
82
+ # Export REPOSITORIES_CONTEXT to bash profile for shell sessions
83
+ if ENV["REPOSITORIES_CONTEXT"]
84
+ profile_file = File.expand_path("~/.bashrc")
85
+ existing_content = File.exist?(profile_file) ? File.read(profile_file) : ""
86
+
87
+ # Remove old export line if present
88
+ existing_content.gsub!(/^export REPOSITORIES_CONTEXT=.*$/, "")
89
+
90
+ # Add new export at the end
91
+ additions = "\nexport REPOSITORIES_CONTEXT=\"#{ENV['REPOSITORIES_CONTEXT']}\"\n"
92
+ File.write(profile_file, existing_content + additions)
93
+ puts "📝 REPOSITORIES_CONTEXT exported to ~/.bashrc"
94
+ end
95
+ rescue JSON::ParserError => e
96
+ puts "⚠️ Failed to parse REPOSITORIES_CONFIG: #{e.message}"
97
+ end
98
+ end