Class: GithubOrgManager::Manager

Inherits:
Object
  • Object
show all
Defined in:
lib/github_org_manager.rb

Constant Summary collapse

DEV_HOME =

Where your development files are stored

File.join(Dir.home, "dev")
OCTOKIT_PARAMS =

Default login params for Octokit, currently relies on OAuth tokens in ‘~/.netrc`:

( github.com/octokit/octokit.rb#using-a-netrc-file )

{ netrc: true }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(org_name:, dev_home: DEV_HOME, octokit_params: OCTOKIT_PARAMS, &octokit_configuration) ⇒ Manager

Creates a new Manager

Parameters:

  • org_name: (String)

    Organization to pull data from

  • dev_home: (String) (defaults to: DEV_HOME)

    Where development files and repos live on your machine

  • octokit_params (Hash<Symbol, Any>) (defaults to: OCTOKIT_PARAMS)

    Params passed through to Octokit::Client constructor

  • &octokit_configuration (Proc)

    Configuration block passed to Octokit.configure



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/github_org_manager.rb', line 34

def initialize(
  org_name:,
  dev_home: DEV_HOME,
  octokit_params: OCTOKIT_PARAMS,
  &octokit_configuration
)
  path_name = Pathname.new(dev_home)
  File.directory?(path_name) or raise "Directory does not exist: #{path_name}"

  @dev_home = path_name
  @org_name = org_name
  @org_path = File.join(path_name, org_name)

  @client = client(octokit_params:, &octokit_configuration)

  @repos = CLIENT.org_repos(@org_name).to_h do |repo_data|
    [repo_data[:name], repo_data[:html_url]]
  end

  @repo_paths = @repos.to_h do |repo_name, _repo_url|
    [repo_name, File.join(@org_path, repo_name)]
  end
end

Instance Attribute Details

#dev_homeObject (readonly)

Returns the value of attribute dev_home.



19
20
21
# File 'lib/github_org_manager.rb', line 19

def dev_home
  @dev_home
end

#org_nameObject (readonly)

Returns the value of attribute org_name.



19
20
21
# File 'lib/github_org_manager.rb', line 19

def org_name
  @org_name
end

#repo_pathsObject (readonly)

Returns the value of attribute repo_paths.



19
20
21
# File 'lib/github_org_manager.rb', line 19

def repo_paths
  @repo_paths
end

#reposObject (readonly)

Returns the value of attribute repos.



19
20
21
# File 'lib/github_org_manager.rb', line 19

def repos
  @repos
end

Instance Method Details

#client(octokit_params:, &configuration) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/github_org_manager.rb', line 109

def client(octokit_params:, &configuration)
  return @client if defined?(@client)

  Octokit.configure(&configuration) if block_given?

  # Lazy for now, will fix later
  @client = if octokit_params == OCTOKIT_PARAMS
    Octokit::Client.new(netrc: true).tap(&:login)
  else
    Octokit::Client.new(**octokit_params)
  end
end

#ensure_repo_directories_exist!Object

Make sure that every repo in the organization exists on this machine.



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/github_org_manager.rb', line 60

def ensure_repo_directories_exist!
  Dir.mkdir(@org_path) unless Dir.exist?(@org_path)

  Dir.chdir(@org_path) do
    @repos.each do |name, html_url|
      `git clone "#{html_url}"` unless Dir.exist?(@repo_paths[name])
    end
  end

  true
end

#update_repos!Object

Update all repos



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
# File 'lib/github_org_manager.rb', line 73

def update_repos!
  # Hard to update repos which don't exist on the computer, make sure that
  # we have them all already downloaded, or do so
  ensure_repo_directories_exist!

  puts "📦 Updating #{@repo_paths.size} repos: \n"

  @repo_paths.each do |name, path|
    Dir.chdir(path) do
      main_branch = `basename $(git symbolic-ref refs/remotes/origin/HEAD)` || "main"
      current_branch = `git rev-parse --abbrev-ref HEAD`
      on_main = main_branch == current_branch
      no_changes = `git diff --stat`.empty?

      puts "  Updating #{name}:"

      puts "    Stashing any potential changes" unless no_changes
      `git stash` unless no_changes

      puts "    Checking out #{main_branch}" unless on_main
      `git checkout #{main_branch}` unless on_main

      puts "    Pulling changes"
      `git pull`

      puts "    Returning to previous branch #{current_branch}" unless on_main
      `git checkout #{current_branch}` unless on_main

      puts "    Popping stash" unless no_changes
      `git stash pop` unless no_changes
    end
  end

  true
end