wooga_wooget 2.1.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.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.travis.yml +20 -0
  4. data/Gemfile +3 -0
  5. data/Licence.md +21 -0
  6. data/README.md +48 -0
  7. data/Rakefile +80 -0
  8. data/bin/wooget +5 -0
  9. data/lib/wooget.rb +57 -0
  10. data/lib/wooget/build/build_info.rb +64 -0
  11. data/lib/wooget/build/builder.rb +285 -0
  12. data/lib/wooget/cli.rb +293 -0
  13. data/lib/wooget/nuget.rb +96 -0
  14. data/lib/wooget/paket.rb +81 -0
  15. data/lib/wooget/project.rb +42 -0
  16. data/lib/wooget/releasing.rb +112 -0
  17. data/lib/wooget/template/files/README.md.erb +20 -0
  18. data/lib/wooget/template/files/RELEASE_NOTES.md.erb +2 -0
  19. data/lib/wooget/template/files/assemblyinfo.erb +36 -0
  20. data/lib/wooget/template/files/class.erb +15 -0
  21. data/lib/wooget/template/files/csproj.erb +56 -0
  22. data/lib/wooget/template/files/gitignore.erb +13 -0
  23. data/lib/wooget/template/files/metafile.cs.erb +11 -0
  24. data/lib/wooget/template/files/paket.binary.template.erb +17 -0
  25. data/lib/wooget/template/files/paket.dependencies.erb +13 -0
  26. data/lib/wooget/template/files/paket.references.erb +2 -0
  27. data/lib/wooget/template/files/paket.template.erb +22 -0
  28. data/lib/wooget/template/files/sln.erb +32 -0
  29. data/lib/wooget/template/files/test_file.erb +19 -0
  30. data/lib/wooget/template/files/tests_assemblyinfo.erb +36 -0
  31. data/lib/wooget/template/files/tests_csproj.erb +67 -0
  32. data/lib/wooget/template/files/unity_paket.dependencies.erb +12 -0
  33. data/lib/wooget/template/unity.rb +73 -0
  34. data/lib/wooget/template/visual_studio.rb +56 -0
  35. data/lib/wooget/template/wooget_conf.json +13 -0
  36. data/lib/wooget/third_party/paket.bootstrapper.exe +0 -0
  37. data/lib/wooget/third_party/paket.exe +0 -0
  38. data/lib/wooget/third_party/paket.targets +36 -0
  39. data/lib/wooget/third_party/paket.unity3d.bootstrapper.exe +0 -0
  40. data/lib/wooget/third_party/paket.unity3d.exe +0 -0
  41. data/lib/wooget/util/build_error.rb +8 -0
  42. data/lib/wooget/util/misc.rb +91 -0
  43. data/lib/wooget/util/package_list_formatter.rb +59 -0
  44. data/lib/wooget/version.rb +22 -0
  45. data/tests/nuget_feed.xml +3439 -0
  46. data/tests/nuget_package.xml +49 -0
  47. data/tests/nuget_test.rb +27 -0
  48. data/tests/package_test.rb +72 -0
  49. data/tests/unity_test.rb +12 -0
  50. data/wiki/bootstrap.png +0 -0
  51. data/wiki/compiling.png +0 -0
  52. data/wiki/create.png +0 -0
  53. data/wiki/install.png +0 -0
  54. data/wiki/list.png +0 -0
  55. data/wiki/monodevelop.png +0 -0
  56. data/wiki/release.png +0 -0
  57. data/wiki/stupidmenu.png +0 -0
  58. data/wooget.gemspec +33 -0
  59. metadata +244 -0
data/lib/wooget/cli.rb ADDED
@@ -0,0 +1,293 @@
1
+ require 'thor'
2
+ require 'fileutils'
3
+ require 'json'
4
+ require 'pathname'
5
+ require 'activesupport/json_encoder'
6
+ module Wooget
7
+ class CLI < Thor
8
+ include Thor::Actions
9
+ class_option :verbose, :desc => "Spit out tons of logging info", :aliases => "-v", :type => :boolean
10
+ class_option :quiet, :desc => "Suppress stdout", :aliases => "-q", :type => :boolean, default: false
11
+ class_option :path, desc: "Path to the project you want to install things into", default: Dir.pwd
12
+
13
+
14
+ def initialize *args
15
+ super
16
+
17
+ Wooget.log.level = Logger::Severity::DEBUG if self.options[:verbose]
18
+ Wooget.repos[:default] = self.options[:repo] if self.options[:repo]
19
+ end
20
+
21
+ desc "create PACKAGE_NAME", "create a new package"
22
+ option :visual_studio, desc: "Should visual studio files (.csproj .sln) be generated?", type: :boolean, default: true
23
+ option :tests, desc: "Should test project be generated?", type: :boolean, default: true
24
+ option :author, desc: "name to use for author field of nupkg"
25
+
26
+ def create package_name
27
+ proj = Project.new
28
+ proj.create package_name, options
29
+ end
30
+
31
+ desc "build", "build the packages in the current dir"
32
+ option :version, desc:"Version number to prepend to release notes", type: :string, required: true
33
+ option :output, desc: "Dir to place built packages", type: :string, default: "bin"
34
+ option :release_notes, desc: "Release notes to include in the package", type: :string, default: ""
35
+ option :native, desc: "Invoke native build functionality", type: :boolean, default: true
36
+ def build
37
+ package_release_checks
38
+
39
+ p "Preinstall before build"
40
+ invoke "install", [], quiet:true, path:get_path
41
+
42
+ p "Running tests"
43
+ invoke "test", [], path:get_path
44
+
45
+ #templates refs have to be relative to the working dir / project root for paket.exe
46
+ path = Pathname.new(options[:path])
47
+ templates = Dir.glob(File.join(options[:path],"**/*paket.template"))
48
+ templates.map! { |t| Pathname.new(t).relative_path_from(path).to_s}
49
+
50
+ build_options = {
51
+ output_dir: options[:output],
52
+ version:options[:version],
53
+ release_notes: options[:release_notes],
54
+ templates: templates,
55
+ path: options[:path],
56
+ native: options[:native]
57
+ }
58
+
59
+ built_packages = invoke "wooget:packager:build", [], build_options
60
+
61
+ p "#{built_packages.join " & "} built to #{File.expand_path File.join(options[:path],options[:output])}" if built_packages
62
+ end
63
+
64
+ option :repo, desc: "Which repo to use"
65
+ option :push, desc: "Should built package be pushed to repo", default: true, type: :boolean
66
+ option :confirm, desc: "Ask for confirmation before pushing", default: true, type: :boolean
67
+ option :output, desc: "Dir to place built packages", type: :string, default: "bin"
68
+ option :git, desc: "Use git functionality", type: :boolean, default: true
69
+ option :native, desc: "Invoke native build functionality", type: :boolean, default: true
70
+ desc "release", "release package in current dir"
71
+
72
+ def release
73
+ package_release_checks
74
+
75
+ released_packages = invoke "wooget:packager:release", [], options
76
+
77
+ p "#{released_packages.join " & "} released successfully" if released_packages
78
+ end
79
+
80
+ option :repo, desc: "Which repo to use"
81
+ option :push, desc: "Should built package be pushed to repo", default: true, type: :boolean
82
+ option :confirm, desc: "Ask for confirmation before pushing", default: true, type: :boolean
83
+ option :output, desc: "Dir to place built packages", type: :string, default: "bin"
84
+ option :git, desc: "Use git functionality", type: :boolean, default: true
85
+ option :native, desc: "Invoke native build functionality", type: :boolean, default: true
86
+ desc "prerelease", "prerelease package in current dir"
87
+
88
+ def prerelease
89
+ package_release_checks
90
+
91
+ released_packages = invoke "wooget:packager:prerelease", [], options
92
+
93
+ p "#{released_packages.join " & "} prereleased successfully" if released_packages
94
+ end
95
+
96
+ desc "test", "run package tests in mono"
97
+
98
+ def test
99
+ unless Util.is_a_wooget_package_dir(options[:path]) and Dir.exists?(File.join(options[:path],"tests"))
100
+ Wooget.log.error "Can't find a wooget package dir with tests at #{options[:path]}"
101
+ return
102
+ end
103
+
104
+ slns = Dir.glob(File.join(options[:path],"/**/*.sln"))
105
+ sln = slns.select{ |d| not Wooget::Util.is_a_unity_project_dir(File.dirname(d))}.first
106
+
107
+ if sln.nil? or sln.empty?
108
+ Wooget.log.error "Can't find sln file for building test artifacts"
109
+ return
110
+ end
111
+
112
+ nunit = Dir.glob(File.join(options[:path],"/**/nunit-console.exe")).first
113
+ if nunit.nil? or nunit.empty?
114
+ Wooget.log.error "Can't find nunit-console for running tests"
115
+ return
116
+ end
117
+
118
+
119
+ Dir.mktmpdir do |tmp_dir|
120
+ p "Building test assembly.."
121
+ stdout, status = Util.run_cmd("xbuild #{File.expand_path(sln)} /t:Rebuild /p:RestorePackages='False' /p:Configuration='Release' /p:OutDir='#{tmp_dir}/'") { |log| Wooget.no_status_log log}
122
+ raise BuildError, stdout.join unless status == 0
123
+
124
+ Dir[File.join(tmp_dir, "*Tests*.dll")].each do |assembly|
125
+ _, status = Util.run_cmd("mono #{nunit} #{assembly} -nologo -labels -noshadow") { |log| p log}
126
+ p "Exit Status - #{status}"
127
+ end
128
+ end
129
+ end
130
+
131
+ desc "paket ARGS", "call bundled version of paket and pass args"
132
+
133
+ def paket *args
134
+ Wooget::Paket.execute(args.join(" "))
135
+ end
136
+
137
+ desc "paket_unity3d ARGS", "call bundled version of paket.unity3d and pass args"
138
+
139
+ def paket_unity3d *args
140
+ Wooget::Paket.unity3d_execute(args.join(" "))
141
+ end
142
+
143
+ option :force, desc: "Forces the download and reinstallation of all packages.", aliases: "-f", type: :boolean, default: false
144
+ desc "install", "install packages into this unity project"
145
+ def install package=nil
146
+ load_config
147
+
148
+ if Util.is_a_unity_project_dir(options[:path]) or Util.is_a_wooget_package_dir(options[:path])
149
+ if package and Util.is_a_unity_project_dir(options[:path])
150
+ invoke "wooget:unity:install", [package], options
151
+ end
152
+
153
+ Paket.install options
154
+ else
155
+ abort "Project not found at #{options[:path]}"
156
+ end
157
+ p "Installed!"
158
+ end
159
+
160
+ option :force, desc: "Forces the download and reinstallation of all packages.", aliases: "-f", type: :boolean, default: false
161
+ desc "update", "update packages into this unity project"
162
+ def update package=nil
163
+ load_config
164
+
165
+ if Util.is_a_unity_project_dir(options[:path]) or Util.is_a_wooget_package_dir(options[:path])
166
+ Paket.update package, options
167
+ else
168
+ abort "Project not found at #{options[:path]}"
169
+ end
170
+ p "Updated!"
171
+ end
172
+
173
+ desc "bootstrap", "setup environment / project for wooget usage"
174
+ def bootstrap
175
+ assert_dependencies
176
+ p "Dependencies OK"
177
+ load_config
178
+ p "Config OK"
179
+
180
+ if Util.is_a_unity_project_dir options[:path]
181
+ p "Unity project detected - Checking setup"
182
+ invoke "wooget:unity:bootstrap", [], options
183
+ end
184
+ end
185
+
186
+ option :repos, desc: "Which repos to list", type: :array, default: ["main", "universe","legacy","public"]
187
+ option :format, desc: "What format to output results", type: :string, enum: ["shell","json"], default: "shell"
188
+ option :show_binary, desc: "Display binary packages in output", type: :boolean, default: false
189
+ desc "list", "list available packages + version"
190
+ def list package_id=nil
191
+ load_config
192
+
193
+ if package_id
194
+ p PackageListFormatter.format_package package_list_by_repo, options[:format], package_id
195
+ else
196
+ p PackageListFormatter.format_list package_list_by_repo, options[:format], options[:show_binary]
197
+ end
198
+ end
199
+
200
+ option :repos, desc: "Which repos to search", type: :array, default: ["main", "universe","legacy"]
201
+ option :format, desc: "What format to output results", type: :string, enum: ["shell","json"], default: "shell"
202
+ option :show_binary, desc: "Display binary packages in output", type: :boolean, default: false
203
+ desc "search", "search packages by a regex"
204
+ def search pattern
205
+ load_config
206
+
207
+ packages_by_repo = package_list_by_repo pattern
208
+ p PackageListFormatter.format_list packages_by_repo, options[:format], options[:show_binary]
209
+ end
210
+
211
+ private
212
+ def package_list_by_repo(match_pattern=nil)
213
+ packages_by_repo = {}
214
+ packages_by_repo_lock = Mutex.new
215
+
216
+ threads = options[:repos].map do |repo|
217
+ Thread.new do
218
+ url = Wooget.repos[repo] || Wooget.repos[repo.to_sym]
219
+ raise RepoError, "Can't find a repository with name '#{repo}' in the configuration" unless url
220
+
221
+ nuget = Nuget.new
222
+ packages = nuget.invoke "packages", [], repo_url:url
223
+ packages = packages.select { |pkg| pkg.package_id.downcase.match(match_pattern.downcase) } unless match_pattern.nil?
224
+ packages_by_repo_lock.synchronize { packages_by_repo[repo] = packages}
225
+ end
226
+ end
227
+
228
+ threads.each {|t| t.join}
229
+ packages_by_repo
230
+ end
231
+
232
+
233
+ no_commands do
234
+ def load_config
235
+ config_location = File.expand_path(File.join("~", ".wooget"))
236
+ unless File.exists? config_location
237
+ Wooget.log.info "Creating default config at #{config_location}"
238
+
239
+ default_config = File.expand_path(File.join(File.dirname(__FILE__), "template", "wooget_conf.json"))
240
+ FileUtils.cp(default_config, config_location)
241
+ end
242
+
243
+ config = JSON.parse(File.read(config_location), symbolize_names: true)
244
+
245
+ Wooget.credentials.merge! config[:credentials]
246
+ Wooget.repos.merge! config[:repos]
247
+
248
+ if config[:repos][:default]
249
+ Wooget.repos[:default] = config[:repos][:default]
250
+ end
251
+
252
+ #set default repo to whatever was passed on commandline (if anything)
253
+ if options[:repo]
254
+ overridden_repo = Wooget.repos[options[:repo]] || Wooget.repos[options[:repo].to_sym]
255
+ abort "Repo '#{options[:repo]}' not found in conf - options are #{Wooget.repos.keys.join(", ")}" unless overridden_repo
256
+
257
+ Wooget.repos[:default] = overridden_repo
258
+ end
259
+
260
+ Wooget.log.debug "Acting as #{Wooget.credentials[:username]}"
261
+ Wooget.log.debug "Default repo is #{Wooget.repo}"
262
+ end
263
+ end
264
+
265
+ private
266
+
267
+
268
+ def assert_package_dir
269
+ abort "#{ get_path} doesn't appear to be a wooget package dir" unless Util.is_a_wooget_package_dir get_path
270
+ end
271
+
272
+ def get_path
273
+ path = Pathname.new(options[:path])
274
+ path.absolute? ? path : File.join(Dir.pwd, options[:path])
275
+ end
276
+
277
+ def assert_dependencies
278
+ %w( mono ).each do |dep|
279
+ `type #{dep}`
280
+ abort "Couldn't find #{dep} - please install!" unless $?.exitstatus == 0
281
+ end
282
+ end
283
+
284
+ def package_release_checks
285
+ assert_package_dir
286
+ load_config
287
+ end
288
+
289
+ def p msg
290
+ say msg unless options[:quiet]
291
+ end
292
+ end
293
+ end
@@ -0,0 +1,96 @@
1
+ require 'ostruct'
2
+ require 'oga'
3
+ require 'curb'
4
+
5
+ module Wooget
6
+ class Nuget < Thor
7
+ option :repo_url, desc: "url to the repo", required: true
8
+ desc "packages", "get packages for a repo"
9
+
10
+ def packages
11
+ Wooget.log.info "Fetching package list for #{options[:repo_url]} ..."
12
+
13
+ url = ""
14
+ if options[:repo_url] == Wooget.repos[:public]
15
+ url = "https://packages.nuget.org/api/v2/Search?searchTerm=%27wooget%27"
16
+ else
17
+ url = options[:repo_url] + '/Search?$orderby=Id&$filter=IsLatestVersion&searchterm='
18
+ end
19
+
20
+ c = Curl::Easy.new(url)
21
+ c.username = Wooget.credentials[:username]
22
+ c.password = Wooget.credentials[:password]
23
+
24
+ c.perform
25
+
26
+ Nuget.from_xml c.body_str
27
+ end
28
+
29
+ def self.from_xml file
30
+ if file.is_a? String and File.exists? file
31
+ file = File.open(file)
32
+ end
33
+
34
+ doc = Oga.parse_xml(file)
35
+
36
+ entries = doc.css "entry"
37
+ entries.map do |e|
38
+ id = e.at_css("title").text()
39
+ url = e.at_css("id").text()
40
+ props_xml = e.at_css("properties").children
41
+ properties = props_xml.inject({}) do |hsh, node|
42
+ hsh[node.name] = node.text() if node.respond_to? :name
43
+ hsh
44
+ end
45
+
46
+ Package.new id, url, properties
47
+ end
48
+ end
49
+ end
50
+
51
+ class Package
52
+ attr_reader :properties, :url, :package_id
53
+
54
+ attr_reader :id, :version, :normalized_version, :authors, :copyright, :created, :dependencies, :description, :download_count
55
+ attr_reader :gallery_details_url, :icon_url, :is_latest_version, :is_absolute_latest_version, :is_prerelease, :language, :last_updated
56
+ attr_reader :published, :package_hash, :package_hash_algorithm, :package_size, :project_url, :report_abuse_url, :release_notes
57
+ attr_reader :require_license_acceptance, :license_url, :summary, :tags
58
+
59
+ attr_accessor :has_binary, :is_binary
60
+
61
+ def initialize package_id, url, properties
62
+ @package_id = package_id
63
+ @url = url
64
+ @properties = properties || {}
65
+
66
+ apply_properties
67
+ end
68
+
69
+ #
70
+ # discern between source and binary packages
71
+ def self.process_binary_packages(packages)
72
+ packages.each do |package|
73
+ package.is_binary = (package.package_id =~ /Binary/ or packages.any? { |p| p.package_id == package.package_id + ".Source" })
74
+ package.has_binary = packages.any? do |p|
75
+ (p.package_id != package.package_id and p.package_id == package.package_id.chomp(".Source"))\
76
+ or p.package_id == package.package_id + ".Binary"
77
+ end
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def apply_properties
84
+ @properties.each do |k, v|
85
+ if self.respond_to? "#{k.snake_case}".to_sym
86
+
87
+ v = true if v == "true"
88
+ v = false if v == "false"
89
+
90
+ instance_variable_set "@#{k.snake_case}".to_sym, v
91
+ end
92
+ end
93
+ @dependencies = @dependencies.split("|") if @dependencies
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,81 @@
1
+ module Wooget
2
+ class Paket
3
+ @@paket_path = File.expand_path(File.join(__FILE__, "..", "third_party", "paket.exe"))
4
+ @@unity3d_path = File.expand_path(File.join(__FILE__, "..", "third_party", "paket.unity3d.exe"))
5
+
6
+ def self.execute args
7
+ cmd = "mono #{ @@paket_path} #{args}"
8
+ Wooget.log.debug "Running #{cmd}"
9
+
10
+ exec cmd
11
+ end
12
+
13
+ def self.unity3d_execute args
14
+ cmd = "mono #{@@unity3d_path} #{args}"
15
+ Wooget.log.debug "Running #{cmd}"
16
+
17
+ exec cmd
18
+ end
19
+
20
+ def self.install options={}
21
+ options[:path] ||= Dir.pwd
22
+
23
+ commands = ["#{env_vars} mono #{@@paket_path} install #{"--force" if options[:force]}"]
24
+ commands << "#{env_vars} mono #{@@unity3d_path} install" if Util.is_a_unity_project_dir(options[:path])
25
+
26
+ commands.each do |cmd|
27
+ reason, exitstatus = Util.run_cmd(cmd, options[:path]) { |log| Wooget.no_status_log log }
28
+ unless exitstatus == 0
29
+ Wooget.log.error "Install failed:\n #{reason}"
30
+ break
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.update package=nil, options={}
36
+ options[:path] ||= Dir.pwd
37
+
38
+ commands = ["#{env_vars} mono #{@@paket_path} update #{"nuget #{package}" if package} #{"--force" if options[:force]}"]
39
+ commands << "#{env_vars} mono #{@@unity3d_path} install" if Util.is_a_unity_project_dir(options[:path])
40
+
41
+ commands.each do |cmd|
42
+ reason, exitstatus = Util.run_cmd(cmd, options[:path]) { |log| Wooget.no_status_log log }
43
+ unless exitstatus == 0
44
+ Wooget.log.error "Update failed:\n #{reason}"
45
+ break
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.env_vars
51
+ "USERNAME=#{Wooget.credentials[:username]} PASSWORD=#{Wooget.credentials[:password]}"
52
+ end
53
+
54
+ def self.installed? project_path, package
55
+ abort "Not a valid paket dir - #{project_path}" unless Util.is_a_unity_project_dir(project_path) or Util.is_a_wooget_package_dir(project_path)
56
+
57
+ lock_file = File.join(project_path, "paket.lock")
58
+ return false unless File.exists? lock_file
59
+
60
+ File.open(lock_file).read.lines.any? { |l| l =~ /\s*#{package}\s+/ }
61
+ end
62
+
63
+ def self.should_generate_unity3d_references? path=Dir.pwd
64
+ #if the references file doesnt exist, or it does exist and
65
+ # it contains the automanage tag then we can rewrite it
66
+ auto_manage_tag = "[!automanage!]"
67
+ !File.exists?(File.join(path, "paket.unity3d.references")) or (Util.file_contains? File.join(path, "paket.dependencies"), auto_manage_tag)
68
+ end
69
+
70
+ def self.pack options
71
+ pack_cmd = "#{env_vars} mono #{@@paket_path} pack output #{options[:output]} version #{options[:version]} releaseNotes \"#{options[:release_notes]}\""
72
+ Util.run_cmd(pack_cmd, options[:path] || Dir.pwd) { |log| Wooget.no_status_log log }
73
+ end
74
+
75
+ def self.push auth, url, package
76
+ push_cmd = "#{env_vars} nugetkey=#{auth} mono #{@@paket_path} push url #{url} file #{package}"
77
+ Util.run_cmd(push_cmd) { |log| Wooget.no_status_log log }
78
+ end
79
+
80
+ end
81
+ end