Module: Git::Multi

Defined in:
lib/git/multi.rb,
lib/git/multi/utils.rb,
lib/git/multi/gemspec.rb,
lib/git/multi/version.rb,
lib/git/multi/commands.rb,
lib/git/multi/settings.rb

Defined Under Namespace

Modules: Commands, Nike, Settings

Constant Summary collapse

HOME =
Dir.home
DEFAULT_WORKAREA =
File.join(HOME, 'Workarea')
WORKAREA =
git_option('git.multi.workarea', DEFAULT_WORKAREA)
DEFAULT_TOKEN =

same as Octokit

env_var('OCTOKIT_ACCESS_TOKEN')
TOKEN =
git_option('github.token', DEFAULT_TOKEN)
CACHE =
File.join(HOME, '.git', 'multi')
REPOSITORIES =
File.join(CACHE, 'repositories.byte')
USERS =
git_list('git.multi.users')
ORGANIZATIONS =
git_list('git.multi.organizations')
MAN_PAGE =
File.expand_path('../../man/git-multi.1', __dir__)
HTML_PAGE =
File.expand_path('../../man/git-multi.html', __dir__)
PIM =
"\nThe only required setting for \\033[1mgit multi\\33[0m is:\n\n\\tgit config --global --add \\033[1mgithub.token\\033[0m <your_github_oauth_token>\n\nThe following settings for \\033[1mgit multi\\33[0m are\noptional, and take 0, 1 or more values:\n\n\\tgit config --global --add \\033[1mgit.multi.users\\033[0m <list_of_github_users>\n\\tgit config --global --add \\033[1mgit.multi.organizations\\033[0m <list_of_github_orgs>\n\nUnless your top-level workarea is `${HOME}/Workarea` you should also set:\n\n\\tgit config --global --add \\033[1mgit.multi.workarea\\033[0m <your_root_workarea>\n\nThanks for using \\033[1mgit multi\\033[0m ... the ultimate multi-repo utility for git!\n\n".freeze
NAME =
'git-multi'.freeze
VERSION =
'2.0.0'.freeze
DEPENDENCY_VERSIONS =
[
  "octokit.rb v#{Octokit::VERSION}",
  "sawyer v#{Sawyer::VERSION}",
  "faraday v#{Faraday::VERSION}",
  "addressable v#{Addressable::VERSION::STRING}",
  "#{RUBY_ENGINE} #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}",
].join(', ').freeze
LONG_VERSION =
"#{NAME} v#{VERSION} (#{DEPENDENCY_VERSIONS})".freeze

Class Method Summary collapse

Class Method Details

.archived_repositories_for(multi_repo = nil) ⇒ Object

lists of repositories with a given state



197
198
199
# File 'lib/git/multi.rb', line 197

def archived_repositories_for(multi_repo = nil)
  repositories_for(multi_repo).find_all(&:archived)
end

.cloned_repositories_for(multi_repo = nil) ⇒ Object



246
247
248
249
250
# File 'lib/git/multi.rb', line 246

def cloned_repositories_for(multi_repo = nil)
  repositories_for(multi_repo).find_all { |project|
    File.directory? project.local_path
  }
end

.env_var(name, default = nil) ⇒ Object



51
52
53
54
# File 'lib/git/multi/utils.rb', line 51

def env_var(name, default = nil)
  value = ENV[name].freeze
  (value.nil? || value.empty?) && default ? default : value
end

.excess_repositories_for(multi_repo = nil) ⇒ Object

derived lists of repositories



213
214
215
216
217
218
# File 'lib/git/multi.rb', line 213

def excess_repositories_for(multi_repo = nil)
  repository_full_names = repositories_for(multi_repo).map(&:full_name)
  local_repositories_for(multi_repo).reject { |project|
    repository_full_names.include? project.full_name
  }
end

.forked_repositories_for(multi_repo = nil) ⇒ Object



201
202
203
# File 'lib/git/multi.rb', line 201

def forked_repositories_for(multi_repo = nil)
  repositories_for(multi_repo).find_all(&:fork)
end

.git_list(name, default = nil) ⇒ Object



47
48
49
# File 'lib/git/multi/utils.rb', line 47

def git_list(name, default = nil)
  git_option(name, default).split(',').map(&:strip)
end

.git_option(name, default = nil) ⇒ Object



42
43
44
45
# File 'lib/git/multi/utils.rb', line 42

def git_option(name, default = nil)
  value = `git config #{name}`.chomp.freeze
  value.empty? && default ? default : value
end

.github_repositoriesObject



97
98
99
100
101
102
# File 'lib/git/multi.rb', line 97

def github_repositories
  @github_repositories ||= (
    USERS.map { |user| @github_user_repositories[user] } +
    ORGANIZATIONS.map { |org| @github_org_repositories[org] }
  ).flatten
end

.github_repositories_for(multi_repo = nil) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/git/multi.rb', line 104

def github_repositories_for(multi_repo = nil)
  case (owner = multi_repo)
  when nil
    github_repositories
  when *USERS
    @github_user_repositories[owner]
  when *ORGANIZATIONS
    @github_org_repositories[owner]
  else
    raise "Unknown multi repo: #{multi_repo}"
  end
end

.local_repositoriesObject



65
66
67
68
69
70
# File 'lib/git/multi.rb', line 65

def local_repositories
  @local_repositories ||= (
    USERS.map { |user| @local_user_repositories[user] } +
    ORGANIZATIONS.map { |org| @local_org_repositories[org] }
  ).flatten
end

.local_repositories_for(multi_repo = nil) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/git/multi.rb', line 72

def local_repositories_for(multi_repo = nil)
  case (owner = multi_repo)
  when nil
    local_repositories
  when *USERS
    @local_user_repositories[owner]
  when *ORGANIZATIONS
    @local_org_repositories[owner]
  else
    raise "Unknown multi repo: #{multi_repo}"
  end
end

.missing_repositories_for(multi_repo = nil) ⇒ Object



240
241
242
243
244
# File 'lib/git/multi.rb', line 240

def missing_repositories_for(multi_repo = nil)
  repositories_for(multi_repo).find_all { |project|
    !File.directory? project.local_path
  }
end

.private_repositories_for(multi_repo = nil) ⇒ Object



205
206
207
# File 'lib/git/multi.rb', line 205

def private_repositories_for(multi_repo = nil)
  repositories_for(multi_repo).find_all(&:private)
end

.refresh_repositoriesObject

manage the local repository cache



121
122
123
124
125
126
127
# File 'lib/git/multi.rb', line 121

def refresh_repositories
  File.directory?(CACHE) || FileUtils.mkdir_p(CACHE)

  File.open(REPOSITORIES, 'wb') do |file|
    Marshal.dump(github_repositories, file)
  end
end

.repositoriesObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/git/multi.rb', line 153

def repositories
  if File.size?(REPOSITORIES)
    # rubocop:disable Security/MarshalLoad
    @repositories ||= Marshal.load(File.read(REPOSITORIES)).tap do |projects|
      projects.each_with_index do |project, index|
        # ensure 'project' has handle on an Octokit client
        project.client = Git::Hub.send(:client)
        # adorn 'project', which is a Sawyer::Resource
        project.parent_dir = Pathname.new(File.join(WORKAREA, project.owner.))
        project.local_path = Pathname.new(File.join(WORKAREA, project.full_name))
        project.fractional_index = "#{index + 1}/#{projects.count}"
        # fix 'project' => https://github.com/octokit/octokit.rb/issues/727
        project.compliant_ssh_url = 'ssh://' + project.ssh_url.split(':', 2).join('/')
        # remove optional '.git' suffix from '[email protected]:pvdb/git-multi.git'
        project.abbreviated_ssh_url = project.ssh_url.chomp('.git')
        # extend 'project' with 'just do it' capabilities
        project.extend Nike
      end
    end
    # rubocop:enable Security/MarshalLoad
  else
    refresh_repositories
    repositories # retry
  end
end

.repositories_for(multi_repo = nil) ⇒ Object

lists of repos for a given multi-repo



183
184
185
186
187
188
189
190
191
# File 'lib/git/multi.rb', line 183

def repositories_for(multi_repo = nil)
  if multi_repo.nil?
    repositories
  else
    repositories.find_all { |repository|
      repository.owner. == multi_repo
    }
  end
end

.spurious_repositories_for(multi_repo = nil) ⇒ Object



227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/git/multi.rb', line 227

def spurious_repositories_for(multi_repo = nil)
  cloned_repositories_for(multi_repo).find_all { |project|
    origin_url = `git -C #{project.local_path} config --get remote.origin.url`.chomp
    ![
      project.clone_url,
      project.ssh_url,
      project.compliant_ssh_url,
      project.abbreviated_ssh_url,
      project.git_url,
    ].include? origin_url
  }
end

.stale_repositories_for(multi_repo = nil) ⇒ Object



220
221
222
223
224
225
# File 'lib/git/multi.rb', line 220

def stale_repositories_for(multi_repo = nil)
  repository_full_names = github_repositories_for(multi_repo).map(&:full_name)
  repositories_for(multi_repo).reject { |project|
    repository_full_names.include? project.full_name
  }
end

.valid?(multi_repo) ⇒ Boolean

multi-repo support

Returns:

  • (Boolean)


49
50
51
# File 'lib/git/multi.rb', line 49

def valid?(multi_repo)
  (USERS + ORGANIZATIONS).include? multi_repo
end