pkgr 0.2.0 → 0.3.0

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.
data/README.md CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  Plug this [Railtie](http://api.rubyonrails.org/classes/Rails/Railtie.html)
4
4
  into your Rails 3 app (ruby1.9 only), and you'll be ready to package your
5
- Rails app as a DEB package. RPM support could be added in the short future.
5
+ Rails app as a DEB package. RPM support could/will be added in the short
6
+ future.
7
+
8
+ This gem originates from hours spent trying to figure out how to package a
9
+ Ruby app for CentOS, and then Debian. It's definitely not trivial, because
10
+ there are so many pieces to put together before getting something working.
11
+ Hopefully this will save time for everyone :)
12
+
13
+ Fair warning: there are probably a few things that could be done better, or in
14
+ a more standard way. Feel free to open an issue and/or a pull-request.
6
15
 
7
16
  ## Why?
8
17
 
@@ -59,6 +68,8 @@ The default target installation directory for the other app files will be
59
68
  [`thin`](http://code.macournoyer.com/thin/) web server. Don't forget to add
60
69
  `thin` to your Gemfile!
61
70
 
71
+ * Your Rails application must have a `config.ru` file.
72
+
62
73
  * Your application must be checked into a **Git** repository. Your name and
63
74
  email is taken from the git configuration, and the changelog is populated
64
75
  based on the git log between two versions.
@@ -252,7 +263,7 @@ Now you can send a first request:
252
263
 
253
264
  Obviously this app does nothing, so you'll get a 404. So go back to building your app, and then just type `rake pkgr:bump:patch` and `HOST=debian-build-machine rake pkgr:build:deb` to generate a new package !
254
265
 
255
- ## Release it (debian)
266
+ ### Release it (debian)
256
267
 
257
268
  As of 0.2.0, you can now release the latest package on a server, and add it to
258
269
  your list of APT sources for easy installation. In the following we'll assume
@@ -368,6 +379,41 @@ Once you're ready to package your app, just run the following commands:
368
379
  app. Next step is probably to upload it to a local apt repository, and then
369
380
  a simple `apt-get install my-app` will install everything. Enjoy!
370
381
 
382
+ ## CLI usage
383
+
384
+ Starting from version 0.3.0, pkgr now comes with an executable, which allows
385
+ to package any app stored in a git repository with one command.
386
+
387
+ For instance, here is how you would package the Redmine app:
388
+
389
+ pkgr --uri https://github.com/edavis10/redmine --ref master --bump 1.4.1 \
390
+ -c https://raw.github.com/crohr/pkgr/master/examples/redmine/configuration.yml \
391
+ -c https://raw.github.com/crohr/pkgr/master/examples/redmine/database.yml \
392
+ -c https://raw.github.com/crohr/pkgr/master/examples/redmine/pkgr.yml \
393
+ --host debian-build
394
+
395
+ You .deb package will be available in `redmine/pkg/`. In this example, the given `pkgr.yml` configuration file automatically adds a dependency on `mysql-server`, which means that when you install the generated redmine package, it will be ready to be accessed on `0.0.0.0:8000`.
396
+
397
+ Note that for simple projects, you may not need to specify any configuration
398
+ file on the command line. See `pkgr -h` for the list of options available:
399
+
400
+ $ pkgr -h
401
+ * Description
402
+ pkgr 0.2.0 - Package Rails apps effortlessly.
403
+ * Usage
404
+ pkgr --uri GIT_REPOSITORY --config database.yml:http://path/to/database.yml --config ...
405
+
406
+ * Common options
407
+ --uri= Sets the Git repository URI (FILE, HTTP, SSH, GIT, etc.) [required]
408
+ -c, --config= Download a configuration file into the config/ folder of the app (HTTP or FILE URIs)
409
+ -b, --bump= Sets the app version [required]
410
+ -n, --name= Sets the app name [optional]
411
+ --ref= Sets the git reference to checkout [default=master]
412
+ --host= Sets the build machine hostname. If none, the process will stop just before building the package.
413
+
414
+ * Other
415
+ -h, --help Show this message
416
+ --version Show version
371
417
 
372
418
  ## Todo
373
419
 
@@ -378,6 +424,8 @@ Once you're ready to package your app, just run the following commands:
378
424
 
379
425
  * Better debian initd script.
380
426
 
427
+ * Populate dependencies based on gems declared in the Gemfile.
428
+
381
429
  * Some tests.
382
430
 
383
431
  ## Authors
@@ -1,5 +1,7 @@
1
1
  require 'rake'
2
2
  require 'erb'
3
+ require 'pkgr/version'
4
+ require 'yaml'
3
5
 
4
6
  module Pkgr
5
7
  class App
@@ -148,18 +150,24 @@ module Pkgr
148
150
  end
149
151
 
150
152
  # FIXME: this is ugly
151
- def bump!(version_index = :patch)
152
- indices = [:major, :minor, :patch]
153
- index = indices.index(version_index) || raise(ArgumentError, "The given version index is not valid (#{version_index})")
154
- version = @config.fetch('version') { '0.0.0' }
155
- fragments = version.split(".")
156
- fragments[index] = fragments[index].to_i+1
157
- ((index+1)..2).each{|i|
158
- fragments[i] = 0
159
- }
160
- new_version = fragments.join(".")
153
+ def bump!(version_index = :patch, new_version = nil)
154
+ unless version_index == :custom
155
+ indices = [:major, :minor, :patch]
156
+ index = indices.index(version_index) || raise(ArgumentError, "The given version index is not valid (#{version_index})")
157
+ fragments = version.split(".")
158
+ fragments[index] = fragments[index].to_i+1
159
+ ((index+1)..2).each{|i|
160
+ fragments[i] = 0
161
+ }
162
+ new_version = fragments.join(".")
163
+ else
164
+ raise ArgumentError, "new_version must not be nil when bumping with a :custom version" if new_version.nil?
165
+ end
161
166
 
162
167
  changelog = File.read(debian_file("changelog"))
168
+ dist = (changelog.scan(/#{name} \(#{new_version}-(\d+)\)/).flatten[0].to_i)
169
+ dist += 1 if new_version == version
170
+ dist = 1 if dist == 0
163
171
 
164
172
  last_commit = changelog.scan(/\s+\* ([a-z0-9]{7}) /).flatten[0]
165
173
 
@@ -171,7 +179,7 @@ module Pkgr
171
179
  raise "Command failed. Aborting."
172
180
  else
173
181
  content_changelog = [
174
- "#{name} (#{new_version}-1) unstable; urgency=low",
182
+ "#{name} (#{new_version}-#{dist}) unstable; urgency=low",
175
183
  "",
176
184
  result.split("\n").reject{|l| l =~ / v#{version}/}.map{|l| " * #{l}"}.join("\n"),
177
185
  "",
@@ -189,7 +197,7 @@ module Pkgr
189
197
 
190
198
  puts "Committing changelog and version file..."
191
199
  files_to_commit = [debian_file('changelog'), @config['_path']]
192
- sh "git add #{files_to_commit.join(" ")} && git commit -m 'v#{new_version}' #{files_to_commit.join(" ")}"
200
+ sh "git add #{files_to_commit.join(" ")} && git commit -m '[pkgr] v#{new_version}-#{dist}' #{files_to_commit.join(" ")}"
193
201
  end
194
202
  end
195
203
 
@@ -215,7 +223,7 @@ module Pkgr
215
223
  def debian_steps
216
224
  target_vendor = "vendor/bundle/ruby/1.9.1"
217
225
  [
218
- "sudo apt-get install #{debian_runtime_dependencies(true).join(" ")} -y",
226
+ # "sudo apt-get install #{debian_runtime_dependencies(true).join(" ")} -y",
219
227
  "sudo apt-get install #{debian_build_dependencies(true).join(" ")} -y",
220
228
  # Vendor bundler
221
229
  "gem1.9.1 install bundler --no-ri --no-rdoc --version #{bundler_version} -i #{target_vendor}",
@@ -248,8 +256,8 @@ module Pkgr
248
256
  end
249
257
 
250
258
  def debian_file(filename)
251
- file = File.join(Pkgr::DEBIAN_DIR, filename)
252
- return nil unless File.exist?(file)
259
+ file = File.join(root, Pkgr::DEBIAN_DIR, filename)
260
+ raise "The debian/changelog file does not exist. Please generate it first." unless File.exist?(file)
253
261
  file
254
262
  end
255
263
  end
@@ -0,0 +1,164 @@
1
+ require 'open-uri'
2
+ require 'fileutils'
3
+ require 'pkgr'
4
+ require 'uri'
5
+
6
+ module Pkgr
7
+ class CLI
8
+ include Rake::DSL
9
+
10
+ class Error < StandardError; end
11
+
12
+ attr_reader :errors
13
+ attr_reader :uri
14
+ attr_reader :dir
15
+ attr_reader :config_files
16
+ attr_reader :version
17
+ attr_reader :name
18
+ attr_reader :app
19
+ attr_reader :host
20
+ attr_reader :ref
21
+
22
+ def initialize(opts = {})
23
+ @errors = []
24
+ @uri, @config_files, @version, @name, @host, @ref = opts.values_at(
25
+ :uri, :config_files, :version, :name, :host, :ref
26
+ )
27
+ @app = nil
28
+ end
29
+
30
+ def run
31
+ raise Error, "Can't run pkgr: #{errors.join(", ")}" unless valid?
32
+ clone_repository
33
+ Dir.chdir(dir) do
34
+ checkout
35
+ copy_remote_config_files
36
+ copy_example_config_files
37
+ setup
38
+ bundle
39
+ configure_app
40
+ generate
41
+ bump
42
+ build
43
+ end
44
+ end
45
+
46
+ def valid?
47
+ @errors.clear
48
+ @errors.push("You must pass a repository URI through --uri") if uri.nil?
49
+ @errors.push("You must pass a version number through --bump") if version.nil?
50
+ @errors.empty?
51
+ end
52
+
53
+ def build
54
+ if host.nil?
55
+ puts "Can't build the package. You must pass the --host option for this."
56
+ else
57
+ @app.build_debian_package(host)
58
+ end
59
+ end
60
+
61
+ def bump
62
+ @app.bump!(:custom, version)
63
+ end
64
+
65
+ def bundle
66
+ sh "bundle install"
67
+ sh "git add -f Gemfile.lock"
68
+ sh "if git status --porcelain | grep Gemfile.lock; then git commit -m '[pkgr] Update Gemfile.lock.'; fi"
69
+ end
70
+
71
+ def checkout
72
+ sh "if git branch | grep '#{pkgr_branch}'; then git checkout #{pkgr_branch}; else git checkout -b #{pkgr_branch} #{ref}; fi"
73
+ end
74
+
75
+ def clone_repository
76
+ parsed_uri = URI.parse(uri)
77
+ case parsed_uri.scheme
78
+ when nil, "file"
79
+ @dir = parsed_uri.path
80
+ else
81
+ @dir = File.basename(uri, ".git")
82
+ sh "git clone #{uri}"
83
+ end
84
+ @dir = File.expand_path @dir
85
+ end
86
+
87
+ def configure_app
88
+ @app = Pkgr::App.new(dir, "config/pkgr.yml")
89
+ @app.config['git_ref'] = pkgr_branch
90
+ @app.config['config_files'].push(*Dir["config/*.yml"].map{|f| File.basename(f)}).uniq!
91
+ if name.nil?
92
+ @app.config['name'] = File.basename(dir) if @app.name.nil?
93
+ else
94
+ @app.config['name'] = name
95
+ end
96
+ raise Error, "The app is not correctly configured: #{@app.errors.join(", ")}" unless @app.valid?
97
+ @app.write_config
98
+ end
99
+
100
+ # Download the given config files
101
+ def copy_remote_config_files
102
+ (config_files || []).each do |file|
103
+ filename, file_uri = file.split("::")
104
+ if file_uri.nil?
105
+ file_uri = filename
106
+ filename = File.basename(file_uri)
107
+ end
108
+
109
+ file_uri = File.expand_path(file_uri) if URI.parse(file_uri).scheme.nil?
110
+ target = "config/#{filename}"
111
+ puts "Copying #{file_uri} into #{target}..."
112
+ File.open(target, "w+") { |f| f << open(file_uri).read }
113
+ end
114
+ end
115
+
116
+ def copy_example_config_files
117
+ [".example", ".dist"].each do |pattern|
118
+ Dir["config/*.yml#{pattern}"].each do |file|
119
+ target = File.basename(file, pattern)
120
+ unless File.exist?("config/#{target}")
121
+ FileUtils.cp(file, "config/#{target}")
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ def generate
128
+ @app.generate_required_files
129
+ sh "git add debian/"
130
+ sh "if git status --porcelain | grep debian/; then git commit -m '[pkgr] Add debian files.'; fi"
131
+ sh "git add bin/"
132
+ sh "if git status --porcelain | grep bin/; then git commit -m '[pkgr] Add executable file.'; fi"
133
+ end
134
+
135
+ def pkgr_branch
136
+ "pkgr-#{ref}"
137
+ end
138
+
139
+ def setup
140
+ Pkgr.setup(dir)
141
+
142
+ gemfile = File.read("Gemfile")
143
+ unless gemfile =~ /$gem 'pkgr'/
144
+ File.open("Gemfile", "a") do |f|
145
+ f.puts
146
+ f.puts "gem 'pkgr'"
147
+ end
148
+ end
149
+
150
+ unless gemfile =~ /$gem 'thin'/
151
+ File.open("Gemfile", "a") do |f|
152
+ f.puts
153
+ f.puts "gem 'pkgr'"
154
+ end
155
+ end
156
+
157
+ sh "git add Gemfile"
158
+ sh" if git status --porcelain | grep Gemfile; then git commit -m '[pkgr] Update Gemfile.'; fi"
159
+ sh "git add -f config/*.yml"
160
+ sh" if git status --porcelain | grep config/*.yml; then git commit -m '[pkgr] Update configuration files.'; fi"
161
+ end
162
+ end
163
+
164
+ end
@@ -23,10 +23,10 @@ namespace :pkgr do
23
23
  end
24
24
 
25
25
  namespace :bump do
26
- %w{patch minor major}.each do |version|
27
- desc "Increments the #{version} version by one"
26
+ %w{patch minor major custom}.each do |version|
27
+ desc "Increments the #{version} version. If using :custom, then you can pass a specific VERSION environment variable."
28
28
  task version.to_sym do
29
- APP.bump!(version.to_sym)
29
+ APP.bump!(version.to_sym, ENV.fetch('VERSION'))
30
30
  end
31
31
  end
32
32
  end
@@ -1,3 +1,3 @@
1
1
  module Pkgr
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pkgr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -16,17 +16,17 @@ dependencies:
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0.8'
22
- type: :development
21
+ version: '0'
22
+ type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: '0.8'
29
+ version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rspec
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -53,6 +53,7 @@ extra_rdoc_files:
53
53
  - README.md
54
54
  files:
55
55
  - lib/pkgr/app.rb
56
+ - lib/pkgr/cli.rb
56
57
  - lib/pkgr/data/bin/executable
57
58
  - lib/pkgr/data/config/pre_boot.rb
58
59
  - lib/pkgr/data/debian/changelog