pkgr 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +50 -2
- data/lib/pkgr/app.rb +23 -15
- data/lib/pkgr/cli.rb +164 -0
- data/lib/pkgr/pkgr.rake +3 -3
- data/lib/pkgr/version.rb +1 -1
- metadata +7 -6
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
|
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
|
-
|
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
|
data/lib/pkgr/app.rb
CHANGED
@@ -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
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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}
|
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
|
-
|
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
|
data/lib/pkgr/cli.rb
ADDED
@@ -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
|
data/lib/pkgr/pkgr.rake
CHANGED
@@ -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
|
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
|
data/lib/pkgr/version.rb
CHANGED
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.
|
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
|
22
|
-
type: :
|
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
|
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
|