Class: Kettle::Dev::DvcsCLI

Inherits:
Object
  • Object
show all
Defined in:
lib/kettle/dev/dvcs_cli.rb

Overview

CLI to normalize git remotes across GitHub, GitLab, and Codeberg.

  • Defaults: origin=github, protocol=ssh, gitlab remote name=gl, codeberg remote name=cb
  • Creates/aligns remotes and an ‘all’ remote that pulls only from origin, pushes to all

Usage:
kettle-dvcs [options] [ORG] [REPO]

Options:
–origin [github|gitlab|codeberg] Choose which forge is origin (default: github)
–protocol [ssh|https] Use git+ssh or HTTPS URLs (default: ssh)
–gitlab-name NAME Remote name for GitLab (default: gl)
–codeberg-name NAME Remote name for Codeberg (default: cb)
–force Accept defaults; non-interactive

Behavior:

  • Aligns or creates remotes for github, gitlab, and codeberg with consistent org/repo and protocol
  • Renames existing remotes to match chosen naming scheme when URLs already match
  • Creates an “all” remote that fetches from origin only and pushes to all three forges
  • Attempts to fetch from each forge to determine availability and updates README federation summary

Examples:

Non-interactive run with defaults (origin: github, protocol: ssh)

kettle-dvcs --force my-org my-repo

Use GitLab as origin and HTTPS URLs

kettle-dvcs --origin gitlab --protocol https my-org my-repo

Constant Summary collapse

DEFAULTS =
{
  origin: "github",
  protocol: "ssh",
  gh_name: "gh",
  gl_name: "gl",
  cb_name: "cb",
  force: false,
  status: false,
}.freeze
FORGE_MIGRATION_TOOLS =
{
  github: "https://github.com/new/import",
  gitlab: "https://gitlab.com/projects/new#import_project",
  codeberg: "https://codeberg.org/repo/migrate",
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ DvcsCLI

Create the CLI with argv-like arguments

Parameters:

  • argv (Array<String>)

    the command-line arguments (without program name)



48
49
50
51
# File 'lib/kettle/dev/dvcs_cli.rb', line 48

def initialize(argv)
  @argv = argv
  @opts = DEFAULTS.dup
end

Instance Method Details

#run!Integer

Execute the CLI command.
Aligns remotes, configures the all remote, prints remotes, attempts fetches,
and updates README federation status accordingly.

Returns:

  • (Integer)

    exit status code (0 on success; may abort with non-zero)



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
# File 'lib/kettle/dev/dvcs_cli.rb', line 57

def run!
  parse!
  git = ensure_git_adapter!

  if @opts[:status]
    # Status mode: no working tree mutation beyond fetch. Don't require clean tree.
    _, _ = resolve_org_repo(git)
    names = remote_names
    branch = detect_default_branch!(git)
    say("Fetching all remotes for status...")
    # Fetch origin first to ensure origin/<branch> is up to date
    git.fetch(names[:origin]) if names[:origin]
    %i[github gitlab codeberg].each do |forge|
      r = names[forge]
      next unless r && r != names[:origin]

      git.fetch(r)
    end
    show_status!(git, names, branch)
    show_local_vs_origin!(git, branch)
    return 0
  end

  abort!("Working tree is not clean; commit or stash changes before proceeding") unless git.clean?

  org, repo = resolve_org_repo(git)

  names = remote_names
  urls = forge_urls(org, repo)

  # Ensure remotes exist and have desired names/urls
  ensure_remote_alignment!(git, names[:origin], urls[@opts[:origin].to_sym])
  ensure_remote_alignment!(git, names[:github], urls[:github]) if names[:github] && names[:github] != names[:origin]
  ensure_remote_alignment!(git, names[:gitlab], urls[:gitlab]) if names[:gitlab]
  ensure_remote_alignment!(git, names[:codeberg], urls[:codeberg]) if names[:codeberg]

  # Configure "all" remote: fetch only from origin, push to all three
  configure_all_remote!(git, names, urls)

  say("Remotes normalized. Origin: #{names[:origin]} (#{urls[@opts[:origin].to_sym]})")
  show_remotes!(git)
  fetch_results = attempt_fetches!(git, names)
  update_readme_federation_status!(org, repo, fetch_results)
  0
end