zd_hire 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []