knife-github 0.0.3 → 0.0.6

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.
@@ -0,0 +1,104 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+
21
+ class Chef
22
+ class Knife
23
+
24
+ class GithubDownload < Knife
25
+
26
+ deps do
27
+ require 'chef/knife/github_base'
28
+ include Chef::Knife::GithubBase
29
+ require 'chef/mixin/shell_out'
30
+ end
31
+
32
+ banner "knife github download COOKBOOK (options)"
33
+ category "github"
34
+
35
+ option :all,
36
+ :short => "-a",
37
+ :long => "--all",
38
+ :description => "Download all cookbooks from github.",
39
+ :boolean => true
40
+
41
+ option :force,
42
+ :short => "-f",
43
+ :long => "--force",
44
+ :description => "Delete the existing cookbooks if exist.",
45
+ :boolean => true
46
+
47
+ def run
48
+
49
+ #executing shell commands
50
+ extend Chef::Mixin::ShellOut
51
+
52
+ # validate base options from base module.
53
+ validate_base_options
54
+
55
+ # Display information if debug mode is on.
56
+ display_debug_info
57
+
58
+ # Gather all repo information from github.
59
+ all_repos = get_all_repos(@github_organizations.reverse)
60
+
61
+ # Get all chef cookbooks and versions (hopefully chef does the error handeling).
62
+ cookbooks = rest.get_rest("/cookbooks?num_version=1")
63
+
64
+ # Get the cookbook names from the command line
65
+ @cookbook_name = name_args.first unless name_args.empty?
66
+ if @cookbook_name
67
+ repo = all_repos.select { |k,v| v["name"] == @cookbook_name }
68
+ repo_download(repo, @cookbook_name)
69
+ elsif config[:all]
70
+ cookbooks.each do |c,v|
71
+ repo_download(all_repos, c)
72
+ end
73
+ else
74
+ Chef::Log.error("Please specify a cookbook name")
75
+ end
76
+ end
77
+
78
+ def repo_download(repo, cookbook)
79
+ if repo.nil? || repo.empty?
80
+ ui.info("Processing [?] #{cookbook}")
81
+ Chef::Log.info("Cannot find the repository: #{cookbook} within github")
82
+ return nil
83
+ end
84
+
85
+ repo_link = get_repo_clone_link()
86
+ if repo[cookbook].nil? || repo[cookbook][repo_link].nil? || repo[cookbook][repo_link].empty?
87
+ ui.info("Processing [?] #{cookbook}")
88
+ Chef::Log.info("Cannot find the link for the repository with the name: #{cookbook}")
89
+ return nil
90
+ end
91
+
92
+ github_url = repo[cookbook][repo_link]
93
+ cookbook_path = cookbook_path_valid?(cookbook, true)
94
+ unless cookbook_path.nil?
95
+ ui.info("Processing [C] #{cookbook}")
96
+ Chef::Log.info("Cloning repository to: #{cookbook_path}")
97
+ shell_out!("git clone #{github_url} #{cookbook_path}")
98
+ end
99
+ end
100
+
101
+
102
+ end
103
+ end
104
+ end
@@ -25,27 +25,14 @@ class Chef
25
25
 
26
26
  deps do
27
27
  require 'chef/knife/github_base'
28
-
29
28
  include Chef::Knife::GithubBase
29
+ require 'chef/knife/github_baselist'
30
+ include Chef::Knife::GithubBaseList
30
31
  end
31
32
 
32
33
  banner "knife github list [COOKBOOK] (options)"
33
34
  category "github"
34
35
 
35
- option :fields,
36
- :long => "--fields 'NAME, NAME'",
37
- :description => "The fields to output, comma-separated"
38
-
39
- option :fieldlist,
40
- :long => "--fieldlist",
41
- :description => "The available fields to output/filter",
42
- :boolean => true
43
-
44
- option :noheader,
45
- :long => "--noheader",
46
- :description => "Removes header from output",
47
- :boolean => true
48
-
49
36
  option :all,
50
37
  :short => "-a",
51
38
  :long => "--all",
@@ -63,37 +50,30 @@ class Chef
63
50
  # Gather all repo information from github.
64
51
  get_all_repos = get_all_repos(@github_organizations.reverse)
65
52
 
66
-
67
53
  # Get all chef cookbooks and versions (hopefully chef does the error handeling).
68
- cb_and_ver = rest.get_rest("/cookbooks?num_version=1")
54
+ cookbooks = rest.get_rest("/cookbooks?num_version=1")
69
55
 
70
- # Get the github link
71
- git_link = get_github_link(@github_link)
56
+ #Get the github link
57
+ git_link = get_repo_clone_link
72
58
 
73
-
74
59
  # Filter all repo information based on the tags that we can find
75
60
  if config[:fields] || config[:fieldlist]
76
61
  all_repos = get_all_repos
77
62
  config[:fields] = "name" if config[:fields].nil? || config[:fields].empty?
78
- else
79
- all_repos = {}
80
- if config[:all]
81
- get_all_repos.each { |k,v|
82
- cookbook = k
83
- cb_and_ver[k].nil? || cb_and_ver[k]['versions'].nil? ? version = "" : version = cb_and_ver[k]['versions'][0]['version']
84
- gh_url = v["#{git_link}"]
85
- gh_tag = v['latest_tag']
86
- all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'git_url' => gh_url, 'latest_gh_tag' => gh_tag }
87
- }
88
63
  else
89
- cb_and_ver.each { |k,v|
90
- cookbook = k
91
- version = v['versions'][0]['version']
92
- get_all_repos[k].nil? || get_all_repos[k]["#{git_link}"].nil? ? gh_url = ui.color("ERROR: Cannot find cookbook!", :red) : gh_url = get_all_repos[k]["#{git_link}"]
93
- get_all_repos[k].nil? || get_all_repos[k]['latest_tag'].nil? ? gh_tag = ui.color("ERROR: No tags!", :red) : gh_tag = get_all_repos[k]['latest_tag']
94
- all_repos[cookbook] = { 'name' => cookbook, 'latest_cb_tag' => version, 'git_url' => gh_url, 'latest_gh_tag' => gh_tag }
95
- }
96
- end
64
+ all_repos = {}
65
+ if config[:all]
66
+ get_all_repos.each { |k,v|
67
+ cookbooks[k].nil? || cookbooks[k]['versions'].nil? ? version = "" : version = cookbooks[k]['versions'][0]['version']
68
+ all_repos[k] = { 'name' => k, 'latest_cb_tag' => version, 'git_url' => v[git_link], 'latest_gh_tag' => v['latest_tag'] }
69
+ }
70
+ else
71
+ cookbooks.each { |k,v|
72
+ get_all_repos[k].nil? || get_all_repos[k][git_link].nil? ? gh_url = ui.color("ERROR: Cannot find cookbook!", :red) : gh_url = get_all_repos[k][git_link]
73
+ get_all_repos[k].nil? || get_all_repos[k]['latest_tag'].nil? ? gh_tag = ui.color("ERROR: No tags!", :red) : gh_tag = get_all_repos[k]['latest_tag']
74
+ all_repos[k] = { 'name' => k, 'latest_cb_tag' => v['versions'][0]['version'], 'git_url' => gh_url, 'latest_gh_tag' => gh_tag }
75
+ }
76
+ end
97
77
  end
98
78
 
99
79
  # Filter only on the cookbook name if its given on the command line
@@ -104,131 +84,14 @@ class Chef
104
84
  repos = all_repos
105
85
  end
106
86
 
107
- # Displaying information based on the fields and repos
108
- if config[:fields]
109
- object_list = []
110
- config[:fields].split(',').each { |n| object_list << ui.color(("#{n}").strip, :bold) }
111
- else
112
- object_list = [
113
- ui.color('Cookbook', :bold),
114
- ui.color('Github', :bold)
115
- ]
116
- end
87
+ columns = [ 'name,Name', 'git_url,Link' ]
117
88
 
118
- columns = object_list.count
119
- object_list = [] if config[:noheader]
120
-
121
- repos.each do |k,r|
122
- if config[:fields]
123
- config[:fields].downcase.split(',').each { |n| object_list << ((r[("#{n}").strip]).to_s || 'n/a') }
124
- else
125
- object_list << (r['name'] || 'n/a')
126
- object_list << (r['git_url'] || 'n/a')
127
- end
128
- end
129
-
130
- puts ui.list(object_list, :uneven_columns_across, columns)
131
- list_object_fields(repos) if locate_config_value(:fieldlist)
132
- end
133
-
134
- def list_object_fields(object)
135
- # pp object
136
- # return
137
- exit 1 if object.nil? || object.empty?
138
- object_fields = [
139
- ui.color('Key', :bold),
140
- ui.color('Type', :bold),
141
- ui.color('Value', :bold)
142
- ]
143
-
144
- object.first.each do |n|
145
- if n.class == Hash
146
- n.keys.each do |k,v|
147
- object_fields << ui.color(k, :yellow, :bold)
148
- object_fields << n[k].class.to_s
149
- if n[k].kind_of?(Array)
150
- object_fields << '<Array>'
151
- elsif n[k].kind_of?(Hash)
152
- object_fields << '<Hash>'
153
- else
154
- object_fields << ("#{n[k]}").strip.to_s
155
- end
156
- end
157
- end
158
- end
159
-
160
- puts "\n"
161
- puts ui.list(object_fields, :uneven_columns_across, 3)
162
- end
163
-
164
- def get_all_repos(orgs)
165
- # Parse every org and merge all into one hash
166
- repos = {}
167
- orgs.each do |org|
168
- get_repos(org).each { |repo| name = repo['name'] ; repos["#{name}"] = repo }
169
- end
170
- repos
171
- end
172
-
173
- def get_repos(org)
174
- dns_name = get_dns_name(@github_url)
175
- file_cache = "#{ENV['HOME']}/.chef/.#{dns_name.downcase}_#{org.downcase}.cache"
176
- if File.exists?(file_cache)
177
- Chef::Log.debug("#{org} cache is created: " + (Time.now - File.ctime(file_cache)).to_i.to_s + " seconds ago.")
178
- if Time.now - File.ctime(file_cache) > @github_cache
179
- # update cache file
180
- create_cache_file(file_cache, org)
181
- end
89
+ if repos.nil? || repos.empty?
90
+ Chef::Log.error("No repositories found.")
182
91
  else
183
- create_cache_file(file_cache, org)
92
+ display_info(repos, columns )
184
93
  end
185
- # use cache files
186
- JSON.parse(File.read(file_cache))
187
- end
188
-
189
- def create_cache_file(file_cache, org)
190
- Chef::Log.debug("Updating the cache file: #{file_cache}")
191
- result = get_repos_github(org)
192
- File.open(file_cache, 'w') { |file| file.write(JSON.pretty_generate(result)) }
193
- end
194
-
195
-
196
-
197
- def get_repos_github(org)
198
- # Get all repo's for the org from github
199
- arr = []
200
- page = 1
201
- url = @github_url + "/api/" + @github_api_version + "/orgs/" + org + "/repos"
202
- while true
203
- params = { 'page' => page }
204
- result = send_request(url, params)
205
- break if result.nil? || result.count < 1
206
- result.each { |key|
207
- if key['tags_url']
208
- tags = get_tags(key)
209
- key['tags'] = tags unless tags.nil? || tags.empty?
210
- key['latest_tag'] = tags.first['name'] unless tags.nil? || tags.empty?
211
- arr << key
212
- else
213
- arr << key
214
- end
215
- }
216
- page = page + 1
217
- end
218
- arr
219
- end
220
-
221
-
222
- def get_tags(repo)
223
- tags = send_request(repo['tags_url'])
224
- tags
225
- end
226
-
227
94
 
228
- def get_dns_name(url)
229
- url = url.downcase.gsub("http://","") if url.downcase.start_with?("http://")
230
- url = url.downcase.gsub("https://","") if url.downcase.start_with?("https://")
231
- url
232
95
  end
233
96
 
234
97
  end
@@ -0,0 +1,88 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+
21
+ module KnifeGithubSearch
22
+ class GithubSearch < Chef::Knife
23
+
24
+ deps do
25
+ require 'chef/knife/github_base'
26
+ include Chef::Knife::GithubBase
27
+ require 'chef/knife/github_baselist'
28
+ include Chef::Knife::GithubBaseList
29
+ end
30
+
31
+ banner "knife github search STRING (options)"
32
+ category "github"
33
+
34
+ option :link,
35
+ :short => "-l",
36
+ :long => "--link",
37
+ :description => "Show the links instead of the description",
38
+ :boolean => true
39
+
40
+
41
+ def run
42
+
43
+ # validate base options from base module.
44
+ validate_base_options
45
+
46
+ # Display information if debug mode is on.
47
+ display_debug_info
48
+
49
+ # Get the name_args from the command line
50
+ query = name_args.join(' ')
51
+
52
+ if query.nil? || query.empty?
53
+ Chef::Log.error("Please specify a search query")
54
+ exit 1
55
+ end
56
+
57
+ result = github_search_repos(query)
58
+
59
+ if config[:link]
60
+ columns = [ 'score,Score', 'name,Name', "url,URL" ]
61
+ else
62
+ columns = [ 'score,Score', 'name,Name', 'description,Description' ]
63
+ end
64
+
65
+ if result['repositories'].nil? || result['repositories'].empty?
66
+ Chef::Log.error("No results when searching for: " + query)
67
+ else
68
+ items = []
69
+ result['repositories'].each { |n| items << [ "#{n['name']}", n ] }
70
+ display_info(items, columns )
71
+ end
72
+ end
73
+
74
+ def github_search_repos(query, params ={})
75
+ # once the new search function is available, we can use these params
76
+ params['q'] = query
77
+ params['sort'] = 'stars'
78
+ params['order'] = 'desc'
79
+ params['response'] = 'json'
80
+
81
+ url = @github_url + "/api/" + @github_api_version + "/legacy/repos/search/" + query
82
+ Chef::Log.debug("URL: #{url}")
83
+
84
+ send_request(url)
85
+ end
86
+
87
+ end
88
+ end
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module Github
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.6"
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-github
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-14 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-10-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-versioning
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
14
30
  description: Github interaction support for Chef's Knife Command
15
31
  email:
16
32
  - sbotman@schubergphilis.com
@@ -22,10 +38,17 @@ files:
22
38
  - .gitignore
23
39
  - LICENSE
24
40
  - README.md
41
+ - Rakefile
25
42
  - knife-github.gemspec
26
43
  - lib/chef/knife/github_base.rb
44
+ - lib/chef/knife/github_baselist.rb
45
+ - lib/chef/knife/github_cleanup.rb
27
46
  - lib/chef/knife/github_compare.rb
47
+ - lib/chef/knife/github_deploy.rb
48
+ - lib/chef/knife/github_diff.rb
49
+ - lib/chef/knife/github_download.rb
28
50
  - lib/chef/knife/github_list.rb
51
+ - lib/chef/knife/github_search.rb
29
52
  - lib/knife-github/version.rb
30
53
  homepage: https://github.com/schubergphilis/knife-github
31
54
  licenses: []