lib/git/multi.rb in git-multi-2.0.0 vs lib/git/multi.rb in git-multi-2.1.0

- old
+ new

@@ -13,45 +13,56 @@ require 'ext/commify' require 'ext/sawyer/resource' require 'git/hub' -require 'git/multi/utils' +require 'git/multi/config' +require 'git/multi/report' require 'git/multi/version' -require 'git/multi/settings' require 'git/multi/commands' module Git module Multi HOME = Dir.home DEFAULT_WORKAREA = File.join(HOME, 'Workarea') - WORKAREA = git_option('git.multi.workarea', DEFAULT_WORKAREA) + WORKAREA = global_option('git.multi.workarea', DEFAULT_WORKAREA) DEFAULT_TOKEN = env_var('OCTOKIT_ACCESS_TOKEN') # same as Octokit - TOKEN = git_option('github.token', DEFAULT_TOKEN) + TOKEN = global_option('github.token', DEFAULT_TOKEN) - CACHE = File.join(HOME, '.git', 'multi') - REPOSITORIES = File.join(CACHE, 'repositories.byte') + GIT_MULTI_DIR = File.join(HOME, '.git', 'multi') - USERS = git_list('git.multi.users') - ORGANIZATIONS = git_list('git.multi.organizations') + FileUtils.mkdir_p(GIT_MULTI_DIR) # ensure `~/.git/multi` directory exists + GITHUB_CACHE = File.join(GIT_MULTI_DIR, 'repositories.byte') + SUPERPROJECTS_CONFIG = File.join(GIT_MULTI_DIR, 'superprojects.config') + + USERS = global_list('git.multi.users') + ORGANIZATIONS = global_list('git.multi.organizations') + SUPERPROJECTS = global_list('git.multi.superprojects') + + MULTI_REPOS = (USERS + ORGANIZATIONS + SUPERPROJECTS) + MAN_PAGE = File.expand_path('../../man/git-multi.1', __dir__) HTML_PAGE = File.expand_path('../../man/git-multi.html', __dir__) module_function # # multi-repo support # def valid?(multi_repo) - (USERS + ORGANIZATIONS).include? multi_repo + MULTI_REPOS.include? multi_repo end + def full_names_for(superproject) + local_list(SUPERPROJECTS_CONFIG, "superproject.#{superproject}.repo") + end + # # local repositories (in WORKAREA) # @local_user_repositories = Hash.new { |repos, user| @@ -67,20 +78,20 @@ USERS.map { |user| @local_user_repositories[user] } + ORGANIZATIONS.map { |org| @local_org_repositories[org] } ).flatten end - def local_repositories_for(multi_repo = nil) - case (owner = multi_repo) + def local_repositories_for(owner = nil) + case owner when nil - local_repositories + local_repositories # all of them when *USERS @local_user_repositories[owner] when *ORGANIZATIONS @local_org_repositories[owner] else - raise "Unknown multi repo: #{multi_repo}" + raise "Unknown owner: #{owner}" end end # # remote repositories (on GitHub) @@ -99,31 +110,29 @@ USERS.map { |user| @github_user_repositories[user] } + ORGANIZATIONS.map { |org| @github_org_repositories[org] } ).flatten end - def github_repositories_for(multi_repo = nil) - case (owner = multi_repo) + def github_repositories_for(owner = nil) + case owner when nil - github_repositories + github_repositories # all of them when *USERS @github_user_repositories[owner] when *ORGANIZATIONS @github_org_repositories[owner] else - raise "Unknown multi repo: #{multi_repo}" + raise "Unknown owner: #{owner}" end end # # manage the local repository cache # def refresh_repositories - File.directory?(CACHE) || FileUtils.mkdir_p(CACHE) - - File.open(REPOSITORIES, 'wb') do |file| + File.open(GITHUB_CACHE, 'wb') do |file| Marshal.dump(github_repositories, file) end end # @@ -149,26 +158,26 @@ end end def repositories - if File.size?(REPOSITORIES) + if File.size?(GITHUB_CACHE) # 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.login)) - 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('/') + @repositories ||= Marshal.load(File.read(GITHUB_CACHE)).tap do |repos| + repos.each_with_index do |repo, index| + # ensure 'repo' has handle on an Octokit client + repo.client = Git::Hub.send(:client) + # adorn 'repo', which is a Sawyer::Resource + repo.parent_dir = Pathname.new(File.join(WORKAREA, repo.owner.login)) + repo.local_path = Pathname.new(File.join(WORKAREA, repo.full_name)) + repo.fractional_index = "#{index + 1}/#{repos.count}" + # fix 'repo' => https://github.com/octokit/octokit.rb/issues/727 + repo.compliant_ssh_url = 'ssh://' + repo.ssh_url.split(':', 2).join('/') # remove optional '.git' suffix from 'git@github.com:pvdb/git-multi.git' - project.abbreviated_ssh_url = project.ssh_url.chomp('.git') - # extend 'project' with 'just do it' capabilities - project.extend Nike + repo.abbreviated_ssh_url = repo.ssh_url.chomp('.git') + # extend 'repo' with 'just do it' capabilities + repo.extend Nike end end # rubocop:enable Security/MarshalLoad else refresh_repositories @@ -179,16 +188,24 @@ # # lists of repos for a given multi-repo # def repositories_for(multi_repo = nil) - if multi_repo.nil? - repositories - else + case (owner = superproject = multi_repo) + when nil + repositories # all of them + when *USERS, *ORGANIZATIONS repositories.find_all { |repository| - repository.owner.login == multi_repo + repository.owner.login == owner } + when *SUPERPROJECTS + full_names = full_names_for(superproject) + repositories.find_all { |repository| + full_names.include?(repository.full_name) + } + else + raise "Unknown multi repo: #{multi_repo}" end end # # lists of repositories with a given state @@ -210,43 +227,44 @@ # derived lists of repositories # 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 + local_repositories_for(multi_repo).reject { |repo| + repository_full_names.include? repo.full_name } end 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 + repositories_for(multi_repo).reject { |repo| + repository_full_names.include? repo.full_name } end 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 + cloned_repositories_for(multi_repo).find_all { |repo| + origin_url = local_option(repo.local_path, 'remote.origin.url') + ![ - project.clone_url, - project.ssh_url, - project.compliant_ssh_url, - project.abbreviated_ssh_url, - project.git_url, + repo.clone_url, + repo.ssh_url, + repo.compliant_ssh_url, + repo.abbreviated_ssh_url, + repo.git_url, ].include? origin_url } end def missing_repositories_for(multi_repo = nil) - repositories_for(multi_repo).find_all { |project| - !File.directory? project.local_path + repositories_for(multi_repo).find_all { |repo| + !File.directory? repo.local_path } end def cloned_repositories_for(multi_repo = nil) - repositories_for(multi_repo).find_all { |project| - File.directory? project.local_path + repositories_for(multi_repo).find_all { |repo| + File.directory? repo.local_path } end end end