Class: Lich::Util::Update::BranchInstaller

Inherits:
Object
  • Object
show all
Defined in:
documented/common/update/branch_installer.rb

Overview

Handles installation of Lich5 from arbitrary GitHub branches.

Supports both main repository branches and fork branches via owner:branch_name syntax. Downloads tarball archives, validates structure, and delegates to ReleaseInstaller for actual installation.

Instance Method Summary collapse

Constructor Details

#initialize(snapshot_manager, release_installer) ⇒ void

Initializes a new BranchInstaller.

Parameters:

  • snapshot_manager (Object)

    the manager for handling snapshots

  • release_installer (Object)

    the installer for handling releases



27
28
29
30
# File 'documented/common/update/branch_installer.rb', line 27

def initialize(snapshot_manager, release_installer)
  @snapshot_manager = snapshot_manager
  @release_installer = release_installer
end

Instance Method Details

#download_branch_update(branch_spec) ⇒ void

This method returns an undefined value.

Downloads and installs the specified branch update from GitHub.

Parameters:

  • branch_spec (String)

    the branch specification in owner:branch_name format or just branch_name

Raises:

  • StandardError if the branch specification is invalid or download fails



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
# File 'documented/common/update/branch_installer.rb', line 37

def download_branch_update(branch_spec)
  branch_spec = branch_spec.strip
  if branch_spec.empty?
    respond
    respond "Error: Branch specification cannot be empty."
    respond "Usage: #{$clean_lich_char}lich5-update --branch=<branch_name>"
    respond "   Or: #{$clean_lich_char}lich5-update --branch=<owner>:<branch_name>"
    respond
    return
  end

  if branch_spec.include?(':')
    owner, branch_name = branch_spec.split(':', 2)
    repo = "#{owner}/lich-5"
  else
    owner = nil
    branch_name = branch_spec
    repo = GITHUB_REPO
  end

  respond
  respond "Attempting to update to branch: #{branch_name}"
  respond "Repository: #{repo}" if owner
  respond "This will download from GitHub and extract over your current installation."
  respond

  @snapshot_manager.snapshot

  require 'erb'
  encoded_branch_name = ERB::Util.url_encode(branch_name)
  tarball_url = "https://github.com/#{repo}/archive/refs/heads/#{encoded_branch_name}.tar.gz"

  sanitized_branch = branch_name.gsub('/', '-')
  filename = "lich5-branch-#{sanitized_branch}"

  begin
    respond
    respond "Downloading branch '#{branch_name}' from GitHub..."
    respond
    tarball_path = File.join(TEMP_DIR, "#{filename}.tar.gz")
    File.open(tarball_path, "wb") do |file|
      file.write URI.parse(tarball_url).open.read
    end

    extract_dir = File.join(TEMP_DIR, filename)
    FileUtils.mkdir_p(extract_dir)
    Gem::Package.new("").extract_tar_gz(File.open(tarball_path, "rb"), extract_dir)

    extracted_dirs = Dir.children(extract_dir)
    if extracted_dirs.empty?
      raise StandardError, "No directories found in extracted tarball"
    end

    source_dir = File.join(extract_dir, extracted_dirs[0])

    unless @release_installer.validate_lich_structure(source_dir)
      raise StandardError, "Downloaded branch does not appear to be a valid Lich installation"
    end

    version_file_path = File.join(source_dir, "lib", "version.rb")
    extracted_version = @release_installer.extract_version_from_file(version_file_path)

    if extracted_version.nil?
      respond
      respond "Warning: Could not extract version from branch's version.rb file."
      respond "Using existing Lich version identifier: #{LICH_VERSION}"
      extracted_version = LICH_VERSION
    else
      respond
      respond "Detected version from branch: #{extracted_version}"
    end

    @release_installer.perform_update(source_dir, extracted_version)

    Lich::Util::Update.store_branch_tracking(branch_name, repo, extracted_version)

    FileUtils.remove_dir(extract_dir) if File.directory?(extract_dir)
    FileUtils.rm(tarball_path) if File.exist?(tarball_path)

    respond
    respond "Successfully updated to branch: #{branch_name} (version #{extracted_version})"
    respond "Branch tracking: This installation is now tracking branch '#{branch_name}'"
    respond "                 from repository '#{repo}'" if owner
    respond "You should exit the game, then log back in to use the updated version."
    respond
    respond "To check your current branch status, run: #{$clean_lich_char}lich5-update --status"
    respond "Enjoy!"
  rescue OpenURI::HTTPError => e
    respond
    respond "Error: Could not download branch '#{branch_name}'"
    respond "HTTP Error: #{e.message}"
    respond "Please verify the branch name exists on GitHub."
    respond
  rescue StandardError => e
    respond
    respond "Error during branch update: #{e.message}"
    respond "Your installation has been preserved."
    respond "You may want to run '#{$clean_lich_char}lich5-update --revert' if needed."
    respond

    begin
      FileUtils.remove_dir(File.join(TEMP_DIR, filename)) if File.directory?(File.join(TEMP_DIR, filename))
      FileUtils.rm(File.join(TEMP_DIR, "#{filename}.tar.gz")) if File.exist?(File.join(TEMP_DIR, "#{filename}.tar.gz"))
    rescue => cleanup_error
      respond "Warning: Could not clean up temporary files: #{cleanup_error.message}"
    end
  end
end