zd_hire 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: '0971f5f3780f1088ee0d4c38638decdc2016a8fc'
4
+ data.tar.gz: 48025579e091a34a92db35c2fe60c08fcb5c6290
5
+ SHA512:
6
+ metadata.gz: bb8f4e78d4b0f068a15ef9bd16fd9ebbd5cff7738e477d3c6fee7726efa774f3f2c943ed540b9068a95fc0c9dde0b0c4729c71cd346c211b2be5f7b448cd3f16
7
+ data.tar.gz: 7e21272192a87eec7d523cfd8739081b5394c9171f3b9441e6c40b9d402e2d618bb3d91d098029df5c166e5e8b1daf62a1d9d5c9a0f4e6620fd4ec3b38cf3d6f
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .zd_hire
11
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in zd_hire.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # ZdHire
2
+
3
+ Clone orphaned repositories from a Github origin and copy selected issues to the new repo.
4
+
5
+ ## Installation
6
+
7
+ Install the gem and use the command line client:
8
+
9
+ ```bash
10
+ $ gem install zd_hire
11
+ $ zd_hire init
12
+ ```
13
+
14
+ This command will start an interactive shell session and will save your github credentials and origin repo configuration at `~/.zd_hire`.
15
+
16
+ ## Usage
17
+
18
+ ```bash
19
+ $ zd_hide clone
20
+ ```
21
+
22
+ This command will start an interactive shell session and will guide you setting up the repository copy.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "zd_hire"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/zd_hire ADDED
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "zd_hire"
5
+ require 'commander/import'
6
+ require 'octokit'
7
+
8
+ program :name, 'ZdHire'
9
+ program :version, ZdHire::VERSION
10
+ program :description, 'Hire developers using Github'
11
+ default_command :init
12
+
13
+ QUESTIONS = {
14
+ repo: 'Github Repository(user/repo): ',
15
+ issues: 'Github Issue Ids: ',
16
+ target_repo: 'New repository name: '
17
+ }
18
+
19
+ PRIVATE_SECTION_SEPARATOR = '## PRIVATE'
20
+ EVALUATION_SEPARATOR = '## EVALUATION'
21
+ DEFAULT_ISSUE_LABEL = 'default_issue'
22
+
23
+ def token_validator
24
+ ->(token) {
25
+ @client = Octokit::Client.new(access_token: token)
26
+ @client.user rescue false
27
+ }
28
+ end
29
+
30
+ def origin_validator
31
+ ->(repo) {
32
+ return false if repo !~ /\w+\/\w+/
33
+ github.repo(repo) rescue false
34
+ }
35
+ end
36
+
37
+ def target_validator
38
+ ->(target) { target != config.origin_repo }
39
+ end
40
+
41
+ def local_origin_validator
42
+ ->(path) { File.directory?(File.expand_path(path)) }
43
+ end
44
+
45
+ def config
46
+ @config ||= ZdHire::Config.new
47
+ end
48
+
49
+ def github
50
+ @client ||= Octokit::Client.new(access_token: config.github_token)
51
+ end
52
+
53
+ command :init do |c|
54
+ c.syntax = 'zd_hire init'
55
+ c.description = 'Configures ZdHire'
56
+ c.action do |args, options|
57
+ if config.valid?
58
+ say "Current Configuration: #{config.attributes}"
59
+ if agree('Would you like to exit initialization?(y/n) ', true)
60
+ exit
61
+ end
62
+ end
63
+ say 'Initializing Configuration'
64
+
65
+ if agree('Would you like to create a new Github access token?(y/n) ', true)
66
+ system "open https://github.com/settings/tokens"
67
+ end
68
+
69
+ config.github_token = ask("Github access token(needs repo, read:org and read:user scopes): ") do |q|
70
+ q.validate = token_validator
71
+ q.responses.merge!(not_valid: "Couldn't connect to github with token. Try again.")
72
+ end
73
+
74
+ config.origin_repo = ask("Origin Github Repository(username/repo): ") do |q|
75
+ q.validate = origin_validator
76
+ q.responses.merge!(not_valid: "Couldn't retrieve repository with credentials. Use the format 'username/repo'")
77
+ end
78
+
79
+ config.local_path = ask("Local repository path: ") do |q|
80
+ q.validate = local_origin_validator
81
+ q.responses.merge!(not_valid: "Couldn't find repo path in local filesystem. E.g (~/Code/myrepo)")
82
+ end
83
+
84
+ config.branch = ask("Default branch to export: ") { |q| q.default = 'master' }
85
+ config.serialize_to_file
86
+ end
87
+ end
88
+
89
+ command :clone do |c|
90
+ c.action do |args, options|
91
+ if config.valid?
92
+ target = ask(QUESTIONS[:target_repo]) do |q|
93
+ q.validate = target_validator
94
+ q.responses.merge!(not_valid: "Target and origin repositories can't be the same")
95
+ end
96
+ clone_repository(config.origin_repo, target)
97
+ else
98
+ say 'Run `zd_hire init` to configure github keys'
99
+ end
100
+ if agree('Would you like to create a Github Project?(y/n) ', true)
101
+ create_project(target)
102
+ end
103
+ end
104
+ end
105
+
106
+ def origin_default_issue
107
+ @df ||= origin_repo_issues.detect{|issue| issue.labels.any?{ |l| l.name == DEFAULT_ISSUE_LABEL} }
108
+ end
109
+
110
+ def evaluation_items(issue)
111
+ return [] unless issue
112
+ evaluation_text = issue.body.split(EVALUATION_SEPARATOR).last
113
+ evaluation_items = evaluation_text.lines.map(&:chomp)
114
+ evaluation_items.delete('')
115
+ evaluation_items
116
+ end
117
+
118
+ def evaluation_item_report(issue)
119
+ default_items = evaluation_items(origin_default_issue)
120
+ issue_type = issue.title.match(/\[(\w+)\]/)[1] rescue issue.number
121
+ issue_items = evaluation_items(issue)
122
+ (issue_items + default_items).compact.map { |item| [issue_type, item].join(', ') }
123
+ end
124
+
125
+ def presentable_issues
126
+ @presentable ||= origin_repo_issues.reject do |issue|
127
+ issue.number.to_i == origin_default_issue&.number&.to_i
128
+ end
129
+ end
130
+
131
+ def origin_repo_issues(options = {})
132
+ @rp ||= github.issues(config.origin_repo, options).reject(&:pull_request)
133
+ end
134
+
135
+ def copy_and_report_issues(target)
136
+ issues = presentable_issues
137
+ issues.each { |i| say "#{i.number}: #{i.title}" }
138
+ issue_ids = ask('Type Issue IDs separated by spaces: ', Array).map(&:to_i)
139
+ selected_issues = issues.select do |issue|
140
+ issue_ids.include?(issue.number.to_i)
141
+ end
142
+ selected_issues.each { |issue| copy_issue(target, issue) }
143
+ selected_issues.each { |issue| puts evaluation_item_report(issue) }
144
+ end
145
+
146
+ def copy_issue(target, issue)
147
+ public_body, private_section = issue.body.split(PRIVATE_SECTION_SEPARATOR)
148
+ unless private_section
149
+ unless agree("[issue #{issue.number}] Could not identify a private section. Issue may be malformatted. Want to copy anyway?(y/n) ", true)
150
+ return
151
+ end
152
+ end
153
+ github.create_issue(target, issue.title, public_body)
154
+ end
155
+
156
+ def clone_repository(origin, target)
157
+ system(
158
+ [
159
+ "git clone --depth 1 -b master git@github.com:#{origin}.git #{target}",
160
+ "cd #{target}",
161
+ 'rm -rf .git'
162
+ ].join(' && ')
163
+ )
164
+ end
165
+
166
+ def setup_remote(target_dir, remote_repo)
167
+ system(
168
+ [
169
+ "cd #{target_dir}",
170
+ 'git init',
171
+ 'git add .',
172
+ 'git commit -m "first commit"',
173
+ "git remote add origin #{remote_repo.ssh_url}",
174
+ 'git push -u origin master'
175
+ ].join(' && ')
176
+ )
177
+ end
178
+
179
+ def create_project(target)
180
+ user = github.user.login
181
+ organization = choose("Which Github Organization? \n") do |menu|
182
+ menu.choices(*([user] + github.organizations.map(&:login)))
183
+ menu.default = user
184
+ end
185
+ project_name = ask('Project name? ') {|q| q.default = target }
186
+ attrs = repo_attributes
187
+ attrs[:organization] = organization unless user == organization
188
+ attrs[:private] = agree('Private repository?(y/n) ', true)
189
+
190
+ begin
191
+ new_repo = github.create_repository(project_name, attrs)
192
+
193
+ if agree("Would you like setup the local repo?(y/n) ", true)
194
+ setup_remote(target, new_repo)
195
+ end
196
+
197
+ if agree("Would you like to select issues to copy(y/n) ", true)
198
+ copy_and_report_issues(new_repo.full_name)
199
+ end
200
+
201
+ if agree('Would you like to open the project in your browser?(y/n) ', true)
202
+ system "open #{new_repo.html_url}"
203
+ end
204
+ rescue => e
205
+ say "The repository could not be created: #{e.message}"
206
+ end
207
+ end
208
+
209
+ def repo_attributes
210
+ {
211
+ has_issues: true,
212
+ has_wiki: false
213
+ }
214
+ end
@@ -0,0 +1,50 @@
1
+ require 'fileutils'
2
+ require 'yaml'
3
+
4
+ module ZdHire
5
+ class Config
6
+ attr_accessor :github_token, :origin_repo, :local_path, :branch
7
+
8
+ def initialize
9
+ if File.exist?(config_file)
10
+ begin
11
+ deserialize_from_file
12
+ rescue
13
+ FileUtils.rm(config_file)
14
+ end
15
+ end
16
+ end
17
+
18
+ def config_file
19
+ @config_file ||= File.join(File.expand_path('~'), '.zd_hire')
20
+ end
21
+
22
+ def deserialize_from_file
23
+ self.attributes = YAML.load_file(config_file)
24
+ end
25
+
26
+ def serialize_to_file
27
+ File.write(config_file, attributes.to_yaml)
28
+ end
29
+
30
+ def attributes
31
+ {
32
+ github_token: github_token,
33
+ origin_repo: origin_repo,
34
+ local_path: local_path,
35
+ branch: branch,
36
+ }
37
+ end
38
+
39
+ def valid?
40
+ attributes.values.none?(&:nil?)
41
+ end
42
+
43
+ def attributes=(options)
44
+ self.github_token = options[:github_token]
45
+ self.origin_repo = options[:origin_repo]
46
+ self.local_path = options[:local_path]
47
+ self.branch = options[:branch]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module ZdHire
2
+ VERSION = "0.0.1"
3
+ end
data/lib/zd_hire.rb ADDED
@@ -0,0 +1,6 @@
1
+ require "zd_hire/version"
2
+ require "zd_hire/config"
3
+
4
+ module ZdHire
5
+
6
+ end
data/zd_hire.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'zd_hire/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "zd_hire"
8
+ spec.version = ZdHire::VERSION
9
+ spec.authors = ["Alexandre Angelim"]
10
+ spec.email = ["angelim@angelim.com.br"]
11
+
12
+ spec.summary = %q{Code Challenges made easy}
13
+ spec.description = %q{Recruit using Gitub}
14
+ spec.homepage = "http://github.com/angelim/zd_hire"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "bin"
18
+ spec.executables = ["zd_hire"]
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency 'commander', '~> 4.4', '>= 4.4.3'
22
+ spec.add_runtime_dependency 'octokit', '~> 4.9', '>= 4.9.0'
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.12"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ end
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zd_hire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexandre Angelim
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: commander
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.4'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.4.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.4'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 4.4.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: octokit
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.9'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 4.9.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '4.9'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 4.9.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: bundler
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.12'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.12'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rake
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '10.0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '10.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '3.0'
95
+ description: Recruit using Gitub
96
+ email:
97
+ - angelim@angelim.com.br
98
+ executables:
99
+ - zd_hire
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - ".gitignore"
104
+ - ".rspec"
105
+ - ".travis.yml"
106
+ - Gemfile
107
+ - README.md
108
+ - Rakefile
109
+ - bin/console
110
+ - bin/setup
111
+ - bin/zd_hire
112
+ - lib/zd_hire.rb
113
+ - lib/zd_hire/config.rb
114
+ - lib/zd_hire/version.rb
115
+ - zd_hire.gemspec
116
+ homepage: http://github.com/angelim/zd_hire
117
+ licenses: []
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.5.2.1
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Code Challenges made easy
139
+ test_files: []