Class: Lich::Util::Update::CustomRepos

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

Overview

Manages user-registered custom (3rd-party) script repositories.

Allows users to register arbitrary GitHub repos and track individual .lic files from them. Custom repo scripts are synced into per-repo subdirectories under SCRIPT_DIR/custom/.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.allHash

Returns all registered custom repos from UserVars.

Returns:

  • (Hash)

    owner_repo => registration hash



64
65
66
67
# File 'documented/common/update/custom_repos.rb', line 64

def self.all
  data = UserVars.custom_repos
  data.is_a?(Hash) ? data : {}
end

.build_config(owner_repo, registration) ⇒ Hash

Builds a SCRIPT_REPOS-compatible config hash for a custom repo.

Parameters:

  • owner_repo (String)

    e.g. "MahtraDR/dr-scripts"

  • registration (Hash)

    stored registration with :branch key

Returns:

  • (Hash)

    config hash matching SCRIPT_REPOS entry shape



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'documented/common/update/custom_repos.rb', line 44

def self.build_config(owner_repo, registration)
  registration = {} unless registration.is_a?(Hash)
  branch = registration[:branch] || registration['branch'] || 'main'
  {
    display_name: "Custom: #{owner_repo}",
    api_url: "https://api.github.com/repos/#{owner_repo}/git/trees/#{branch}?recursive=1",
    raw_base_url: "https://raw.githubusercontent.com/#{owner_repo}/#{branch}",
    tracking_mode: :explicit,
    script_pattern: /^[^\/]+\.lic$/,
    game_filter: nil,
    default_tracked: [],
    subdirs: {},
    custom: true,
    dest_dir: dest_dir(owner_repo)
  }
end

.dest_dir(owner_repo) ⇒ String

Returns the destination directory for a custom repo's scripts.

Parameters:

  • owner_repo (String)

    e.g. "MahtraDR/dr-scripts"

Returns:



35
36
37
# File 'documented/common/update/custom_repos.rb', line 35

def self.dest_dir(owner_repo)
  File.join(SCRIPT_DIR, 'custom', repo_dir_name(owner_repo))
end

.repo_dir_name(owner_repo) ⇒ String

Converts owner/repo to a filesystem-safe directory name.

Parameters:

  • owner_repo (String)

    e.g. "MahtraDR/dr-scripts"

Returns:

  • (String)

    e.g. "MahtraDR-dr-scripts"



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

def self.repo_dir_name(owner_repo)
  owner_repo.gsub('/', '-')
end

Instance Method Details

#add_custom_repo(owner_repo, branch = nil) ⇒ void

This method returns an undefined value.

Registers a custom repository.

Parameters:

  • owner_repo (String)

    "owner/repo" format

  • branch (String, nil) (defaults to: nil)

    branch name (default: "main")



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

def add_custom_repo(owner_repo, branch = nil)
  unless owner_repo =~ %r{\A[A-Za-z0-9._-]+/[A-Za-z0-9._-]+\z}
    StatusReporter.respond_mono("[lich5-update: Invalid format '#{owner_repo}'. Use owner/repo (e.g. MahtraDR/dr-scripts).]")
    return
  end

  if branch && (branch.empty? || branch !~ /\A[A-Za-z0-9._\/-]+\z/)
    StatusReporter.respond_mono("[lich5-update: Invalid branch name '#{branch}'. Branch names may only contain letters, digits, dots, hyphens, underscores, and slashes.]")
    return
  end

  UserVars.custom_repos = {} unless UserVars.custom_repos.is_a?(Hash)
  if UserVars.custom_repos[owner_repo]
    StatusReporter.respond_mono("[lich5-update: '#{owner_repo}' is already registered.]")
    return
  end

  new_dir = self.class.repo_dir_name(owner_repo)
  collider = UserVars.custom_repos.keys.find { |k| self.class.repo_dir_name(k) == new_dir }
  if collider
    StatusReporter.respond_mono("[lich5-update: '#{owner_repo}' collides with '#{collider}' (both map to directory '#{new_dir}'). Choose a different repo or remove the existing one first.]")
    return
  end

  UserVars.custom_repos[owner_repo] = {
    'branch'   => branch || 'main',
    'added_at' => Time.now.strftime('%Y-%m-%d')
  }
  Vars.save
  StatusReporter.respond_mono("[lich5-update: Registered custom repo '#{owner_repo}' (branch: #{branch || 'main'}).]")
end

#list_custom_reposvoid

This method returns an undefined value.

Displays registered custom repos in a table.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'documented/common/update/custom_repos.rb', line 135

def list_custom_repos
  repos = self.class.all
  if repos.empty?
    StatusReporter.respond_mono("[lich5-update: No custom repos registered. Use --add-custom=owner/repo to add one.]")
    return
  end

  table_rows = []
  table_rows << ['Repository', 'Branch', 'Added', 'Scripts']
  table_rows << :separator

  repos.each do |owner_repo, reg|
    branch = reg[:branch] || reg['branch'] || 'main'
    added = reg[:added_at] || reg['added_at'] || '?'
    tracked = (UserVars.tracked_scripts&.dig(owner_repo) || []).length
    dest = self.class.dest_dir(owner_repo)
    installed = File.directory?(dest) ? Dir.children(dest).count { |f| f.end_with?('.lic') } : 0
    table_rows << [owner_repo, branch, added, "#{tracked} tracked, #{installed} installed"]
  end

  table = Terminal::Table.new(title: 'Custom Repositories', rows: table_rows)
  StatusReporter.respond_mono(table.to_s)
end

#remove_custom_repo(owner_repo) ⇒ void

This method returns an undefined value.

Unregisters a custom repository.

Parameters:

  • owner_repo (String)

    "owner/repo" format



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'documented/common/update/custom_repos.rb', line 110

def remove_custom_repo(owner_repo)
  UserVars.custom_repos = {} unless UserVars.custom_repos.is_a?(Hash)
  unless UserVars.custom_repos.delete(owner_repo)
    StatusReporter.respond_mono("[lich5-update: '#{owner_repo}' is not a registered custom repo.]")
    return
  end

  # Clean up tracked scripts for this repo
  UserVars.tracked_scripts&.delete(owner_repo)
  Vars.save

  dest = self.class.dest_dir(owner_repo)
  if File.directory?(dest)
    files = Dir.children(dest).select { |f| f.end_with?('.lic') }
    if files.any?
      StatusReporter.respond_mono("[lich5-update: Note: #{files.length} script(s) still installed in #{dest}. Delete manually if no longer needed.]")
    end
  end

  StatusReporter.respond_mono("[lich5-update: Removed custom repo '#{owner_repo}'.]")
end