Class: GemContribute::CLI::ForkCloneBranch

Inherits:
Object
  • Object
show all
Defined in:
lib/gem_contribute/cli/fork_clone_branch.rb

Overview

‘gem-contribute fork-clone-branch <gem>/<issue#>`

Performs the full sequence the TUI’s ‘f` keybinding will trigger in Stage 3:

1. Resolve <gem> via the RubyGems Resolver (no lockfile required;
   the lockfile is for discovery via `scan`, not gating here).
2. Read the cached GitHub token; raise AuthRequired with a clear
   `auth login` hint if missing.
3. Look up the viewer's login.
4. If they don't already have a fork, fork the upstream repo.
5. Poll until the fork is reachable (forks return 202 immediately
   but the resource may 404 for a few seconds).
6. `git clone` the fork to `<clone_root>/<owner>/<repo>`.
7. `git checkout -b gem-contribute/issue-<N>` from the default branch.
8. Print the local path on stdout.

The shell-outs use Open3 with explicit args (not strings) to avoid any shell-injection surface.

Constant Summary collapse

DEFAULT_CLONE_ROOT =
File.expand_path("~/code/oss")
BRANCH_PREFIX =
"gem-contribute/issue-"
FORK_READINESS_RETRIES =

12 × 5s = 60s ceiling

12
FORK_READINESS_INTERVAL =
5

Instance Method Summary collapse

Constructor Details

#initialize(stdout: $stdout, stderr: $stderr, resolver: Resolver.new, store: TokenStore.new, adapter_factory: ->(token:) { HostAdapters::GitHubAdapter.new(token: token) }, git: Git.new, clone_root: DEFAULT_CLONE_ROOT, sleeper: ->(s) { Kernel.sleep(s) }) ⇒ ForkCloneBranch

Returns a new instance of ForkCloneBranch.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/gem_contribute/cli/fork_clone_branch.rb', line 32

def initialize(stdout: $stdout,
               stderr: $stderr,
               resolver: Resolver.new,
               store: TokenStore.new,
               adapter_factory: ->(token:) { HostAdapters::GitHubAdapter.new(token: token) },
               git: Git.new,
               clone_root: DEFAULT_CLONE_ROOT,
               sleeper: ->(s) { Kernel.sleep(s) })
  @stdout = stdout
  @stderr = stderr
  @resolver = resolver
  @store = store
  @adapter_factory = adapter_factory
  @git = git
  @clone_root = clone_root
  @sleeper = sleeper
end

Instance Method Details

#run(argv) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/gem_contribute/cli/fork_clone_branch.rb', line 50

def run(argv)
  target = argv.shift
  return print_usage_error if target.nil? || !target.include?("/")

  gem_name, issue = target.split("/", 2)
  adapter = build_adapter
  return 1 if adapter.nil?

  project = resolve_or_fail(gem_name)
  return 1 if project.nil?

  execute(adapter, project, issue)
rescue AuthRequired
  @stderr.puts "Not authenticated. Run `gem-contribute auth login` first."
  1
rescue AdapterError => e
  @stderr.puts "fork-clone-branch failed: #{e.message}"
  1
end