Compare commits
38 Commits
v0.37.0.pr
...
v0.37.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de54f6a5a5 | ||
|
|
0dff116340 | ||
|
|
e053dc8434 | ||
|
|
20f6ba1563 | ||
|
|
557a08ea77 | ||
|
|
8eccc819d6 | ||
|
|
347d4a0184 | ||
|
|
0147f5d284 | ||
|
|
1da034ce66 | ||
|
|
5fc7552572 | ||
|
|
083efe3ae9 | ||
|
|
9d2382a2d2 | ||
|
|
f731daae1a | ||
|
|
b7f0e3f573 | ||
|
|
e7c523dab7 | ||
|
|
9f4f15a29c | ||
|
|
b2dc89c50e | ||
|
|
389bf05800 | ||
|
|
a632a62efd | ||
|
|
2edf6e1c68 | ||
|
|
56158e881b | ||
|
|
6b5ed495d5 | ||
|
|
9652c285f1 | ||
|
|
ba171cc10d | ||
|
|
ebb191adba | ||
|
|
8c3ef1a7af | ||
|
|
cf69c31ae3 | ||
|
|
e16a35da4b | ||
|
|
2490dd2a5b | ||
|
|
2705520496 | ||
|
|
522fee5e9e | ||
|
|
c462473a25 | ||
|
|
224fe94dc2 | ||
|
|
7cb73f5c36 | ||
|
|
1537ddbcc9 | ||
|
|
b04c81dd06 | ||
|
|
ae22d34967 | ||
|
|
9a359efbf7 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,4 +5,4 @@
|
||||
/man/*.markdown
|
||||
/pkg
|
||||
/tags
|
||||
/vendor
|
||||
/vendor
|
||||
|
||||
11
Changelog
11
Changelog
@@ -1,11 +0,0 @@
|
||||
0.26.1 12/05/2011 6160246da0fafe9cf8fde188d94bbc6babc667dc
|
||||
==========================================================
|
||||
|
||||
Merge pull request #103 from csquared/load_env_from_irb [David Dollar]
|
||||
refactor load_env to apply_environment [Chris Continanza]
|
||||
rename load! to load_env! [Chris Continanza]
|
||||
use ./.env as default [Chris Continanza]
|
||||
load contents from env file [Chris Continanza]
|
||||
refactor engine to expose env methods [Chris Continanza]
|
||||
disable email notifications [David Dollar]
|
||||
add travis config [David Dollar]
|
||||
139
Changelog.md
Normal file
139
Changelog.md
Normal file
@@ -0,0 +1,139 @@
|
||||
## 0.37.0 (2012-01-29)
|
||||
|
||||
* put an entire line of output inside a single mutex so we don't cross the streams [David Dollar]
|
||||
* fix race condition with process termination [David Dollar]
|
||||
* allow external custom exporters [Chris Lowder]
|
||||
* fix the test for an empty string in bin/runner [Florian Apolloner]
|
||||
* ensure we have non-nil data, fixes #111 [David Dollar]
|
||||
* make sure error method exists, fixes #104 [David Dollar]
|
||||
* clean up chdir usage [David Dollar]
|
||||
* normalize platform names [David Dollar]
|
||||
* add windows support [David Dollar]
|
||||
* add jruby support [David Dollar]
|
||||
* pass basedir along to the runner script [David Dollar]
|
||||
* harden runner script [David Dollar]
|
||||
* add many missing specs [brainopia]
|
||||
* clean up fakefs usage in specs [brainopia]
|
||||
* runit creates a full path to export directory. [Fletcher Nichol]
|
||||
|
||||
## 0.36.1 (2012-01-18)
|
||||
|
||||
* 0.36.1 [David Dollar]
|
||||
* bump term-ansicolor in gemspec [David Dollar]
|
||||
|
||||
## 0.36.0 (2012-01-17)
|
||||
|
||||
* 0.36.0 [David Dollar]
|
||||
* sync the writer stream [David Dollar]
|
||||
* capture stderr as well [David Dollar]
|
||||
|
||||
## 0.35.0 (2012-01-16)
|
||||
|
||||
* update rake [David Dollar]
|
||||
* 0.35.0 [David Dollar]
|
||||
* Merge pull request #132 from Viximo/feature/concurrency [David Dollar]
|
||||
* Fix export specs [Matt Griffin]
|
||||
* Merge branch 'master' of https://github.com/michaeldwan/foreman into feature/concurrency [Matt Griffin]
|
||||
* default process concurrency is 0 when concurrency options specified, otherwise default concurrency is 1 [Michael Dwan]
|
||||
|
||||
## 0.34.1 (2012-01-16)
|
||||
|
||||
* 0.34.1 [David Dollar]
|
||||
* fix missing start desc [David Dollar]
|
||||
|
||||
## 0.34.0 (2012-01-16)
|
||||
|
||||
* 0.34.0 [David Dollar]
|
||||
* update man page [David Dollar]
|
||||
* update docs for -d [David Dollar]
|
||||
* Merge pull request #101 from ndbroadbent/foreman [David Dollar]
|
||||
* Wrap around to the first colour when all the colours are used [Craig R Webster]
|
||||
* run specs in random order [David Dollar]
|
||||
* update rspec [David Dollar]
|
||||
* pedantry [David Dollar]
|
||||
* Set executable bit on runit run scripts. [Matthijs Langenberg]
|
||||
* Merge pull request #114 from gburt/master [David Dollar]
|
||||
* add more colors [Gabriel Burt]
|
||||
* Added option to specify app_root, if executing a Procfile from a shared location [Nathan Broadbent]
|
||||
|
||||
## 0.33.1 (2012-01-16)
|
||||
|
||||
* 0.33.1 [David Dollar]
|
||||
* Merge pull request #129 from fnichol/resolve-home-template [David Dollar]
|
||||
* Expand template path under user's home directory. [Fletcher Nichol]
|
||||
|
||||
## 0.33.0 (2012-01-15)
|
||||
|
||||
* 0.33.0 [David Dollar]
|
||||
* Revert "Merge pull request #125 from brainopia/master" [David Dollar]
|
||||
|
||||
## 0.32.0 (2012-01-12)
|
||||
|
||||
* 0.32.0 [David Dollar]
|
||||
* Merge pull request #125 from brainopia/master [David Dollar]
|
||||
* Merge pull request #121 from Viximo/feature/run [David Dollar]
|
||||
* Return some whitespace that was accidentally removed [Matt Griffin]
|
||||
* Steal the run method back from Thor so that it can be used in place for exec for running commands in the foreman environment. [Matt Griffin]
|
||||
* Remove old cruft [brainopia]
|
||||
* In case someone wants to use bin/runner directly [brainopia]
|
||||
* Fix for double fork [brainopia]
|
||||
* Use ruby exec which works with escaped cmd and replaces shell [brainopia]
|
||||
* Fix foreman to work with cmds containing pipes and redirects [brainopia]
|
||||
* Add "exec" action to allow execution of arbitrary commands with the app's environment. [Matt Griffin]
|
||||
* tweak readme [David Dollar]
|
||||
|
||||
## 0.31.0 (2012-01-04)
|
||||
|
||||
* 0.31.0 [David Dollar]
|
||||
* make fork more robust [David Dollar]
|
||||
* remove unnecessary debug [David Dollar]
|
||||
* add more information when shutting down [David Dollar]
|
||||
* Merge pull request #110 from lstoll/master [David Dollar]
|
||||
* Use different port ranges for each process type [Lincoln Stoll]
|
||||
|
||||
## 0.30.1 (2011-12-23)
|
||||
|
||||
* 0.30.1 [David Dollar]
|
||||
* require thread for mutex [David Dollar]
|
||||
|
||||
## 0.30.0 (2011-12-22)
|
||||
|
||||
* 0.30.0 [David Dollar]
|
||||
* compatibility with ruby 1.8 [David Dollar]
|
||||
|
||||
## 0.29.0 (2011-12-22)
|
||||
|
||||
* 0.29.0 [David Dollar]
|
||||
* 0.28.0.pre2 [David Dollar]
|
||||
* fix pipe error [David Dollar]
|
||||
* 0.28.0.pre1 [David Dollar]
|
||||
* Merge branch 'fork' [David Dollar]
|
||||
* wip [David Dollar]
|
||||
* wip [David Dollar]
|
||||
* wip [David Dollar]
|
||||
* wip [David Dollar]
|
||||
* wip [David Dollar]
|
||||
|
||||
## 0.27.0 (2011-12-05)
|
||||
|
||||
* 0.27.0 [David Dollar]
|
||||
* add changelog [David Dollar]
|
||||
* Merge pull request #103 from csquared/load_env_from_irb [David Dollar]
|
||||
* refactor load_env to apply_environment [Chris Continanza]
|
||||
* rename load! to load_env! [Chris Continanza]
|
||||
* use ./.env as default [Chris Continanza]
|
||||
* load contents from env file [Chris Continanza]
|
||||
* refactor engine to expose env methods [Chris Continanza]
|
||||
* disable email notifications [David Dollar]
|
||||
* add travis config [David Dollar]
|
||||
|
||||
## 0.26.1 2011-12-05
|
||||
|
||||
* Merge pull request #103 from csquared/load_env_from_irb [David Dollar]
|
||||
* refactor load_env to apply_environment [Chris Continanza]
|
||||
* rename load! to load_env! [Chris Continanza]
|
||||
* use ./.env as default [Chris Continanza]
|
||||
* load contents from env file [Chris Continanza]
|
||||
* refactor engine to expose env methods [Chris Continanza]
|
||||
* disable email notifications [David Dollar]
|
||||
* add travis config [David Dollar]
|
||||
2
Gemfile
2
Gemfile
@@ -15,10 +15,10 @@ group :development do
|
||||
gem 'rake'
|
||||
gem 'ronn'
|
||||
gem 'fakefs', '~> 0.3.2'
|
||||
gem 'rcov', '~> 0.9.8'
|
||||
gem 'rr', '~> 1.0.2'
|
||||
gem 'rspec', '~> 2.0'
|
||||
gem 'ZenTest'
|
||||
gem 'aws-s3'
|
||||
gem "rubyzip"
|
||||
gem "simplecov", :require => false
|
||||
end
|
||||
|
||||
11
Gemfile.lock
11
Gemfile.lock
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
foreman (0.37.0.pre5)
|
||||
foreman (0.37.1)
|
||||
term-ansicolor (~> 1.0.7)
|
||||
thor (>= 0.13.6)
|
||||
|
||||
@@ -20,6 +20,7 @@ GEM
|
||||
hpricot (0.8.2)
|
||||
hpricot (0.8.2-java)
|
||||
mime-types (1.16)
|
||||
multi_json (1.0.4)
|
||||
mustache (0.11.2)
|
||||
parka (0.6.2)
|
||||
crack
|
||||
@@ -27,8 +28,6 @@ GEM
|
||||
thor
|
||||
posix-spawn (0.3.6)
|
||||
rake (0.9.2.2)
|
||||
rcov (0.9.8)
|
||||
rcov (0.9.8-java)
|
||||
rdiscount (1.6.5)
|
||||
rest-client (1.6.1)
|
||||
mime-types (>= 1.16)
|
||||
@@ -46,6 +45,10 @@ GEM
|
||||
diff-lcs (~> 1.1.2)
|
||||
rspec-mocks (2.8.0)
|
||||
rubyzip (0.9.4)
|
||||
simplecov (0.5.4)
|
||||
multi_json (~> 1.0.3)
|
||||
simplecov-html (~> 0.5.3)
|
||||
simplecov-html (0.5.3)
|
||||
term-ansicolor (1.0.7)
|
||||
thor (0.14.6)
|
||||
win32console (1.3.0-x86-mingw32)
|
||||
@@ -64,9 +67,9 @@ DEPENDENCIES
|
||||
parka
|
||||
posix-spawn (~> 0.3.6)
|
||||
rake
|
||||
rcov (~> 0.9.8)
|
||||
ronn
|
||||
rr (~> 1.0.2)
|
||||
rspec (~> 2.0)
|
||||
rubyzip
|
||||
simplecov
|
||||
win32console (~> 1.3.0)
|
||||
|
||||
@@ -25,6 +25,7 @@ Manage Procfile-based applications
|
||||
|
||||
* [man page](http://ddollar.github.com/foreman)
|
||||
* [wiki](http://github.com/ddollar/foreman/wiki)
|
||||
* [changelog](https://github.com/ddollar/foreman/blob/master/Changelog.md)
|
||||
|
||||
## Authors
|
||||
|
||||
@@ -32,7 +33,7 @@ Manage Procfile-based applications
|
||||
David Dollar
|
||||
|
||||
#### Patches contributed by
|
||||
Adam Wiggins, Chris Continanza, Chris Lowder, Craig R Webster, Dan Farina, Dan Peterson, David Dollar, Fletcher Nichol, Gabriel Burt, Gamaliel Toro, Greg Reinacker, Hugues Le Gendre, Hunter Nield, Iain Hecker, Jay Zeschin, Keith Rarick, Khaja Minhajuddin, Lincoln Stoll, Marcos Muino Garcia, Mark McGranaghan, Matt Griffin, Matt Haynes, Matthijs Langenberg, Michael Dwan, Michael van Rooijen, Mike Javorski, Nathan Broadbent, Nathan L Smith, Nick Zadrozny, Phil Hagelberg, Ricardo Chimal, Jr, Thom May, Tom Ward, brainopia, clifff, jc00ke
|
||||
Adam Wiggins, Chris Continanza, Chris Lowder, Craig R Webster, Dan Farina, Dan Peterson, David Dollar, Fletcher Nichol, Florian Apolloner, Gabriel Burt, Gamaliel Toro, Greg Reinacker, Hugues Le Gendre, Hunter Nield, Iain Hecker, Jay Zeschin, Keith Rarick, Khaja Minhajuddin, Lincoln Stoll, Marcos Muino Garcia, Mark McGranaghan, Matt Griffin, Matt Haynes, Matthijs Langenberg, Michael Dwan, Michael van Rooijen, Mike Javorski, Nathan Broadbent, Nathan L Smith, Nick Zadrozny, Phil Hagelberg, Ricardo Chimal, Jr, Thom May, Tom Ward, brainopia, clifff, jc00ke
|
||||
|
||||
## License
|
||||
|
||||
|
||||
190
Rakefile
190
Rakefile
@@ -1,192 +1,6 @@
|
||||
require "rake"
|
||||
require "rspec"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
$:.unshift File.expand_path("../lib", __FILE__)
|
||||
require "foreman"
|
||||
|
||||
task :default => :spec
|
||||
task :release => :man
|
||||
|
||||
desc "Run all specs"
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
t.pattern = 'spec/**/*_spec.rb'
|
||||
end
|
||||
|
||||
desc "Generate RCov code coverage report"
|
||||
task :rcov => "rcov:build" do
|
||||
%x{ open coverage/index.html }
|
||||
end
|
||||
|
||||
RSpec::Core::RakeTask.new("rcov:build") do |t|
|
||||
t.pattern = 'spec/**/*_spec.rb'
|
||||
t.rcov = true
|
||||
t.rcov_opts = [ "--exclude", ".bundle", "--exclude", "spec" ]
|
||||
end
|
||||
|
||||
desc 'Build the manual'
|
||||
task :man do
|
||||
ENV['RONN_MANUAL'] = "Foreman Manual"
|
||||
ENV['RONN_ORGANIZATION'] = "Foreman #{Foreman::VERSION}"
|
||||
sh "ronn -w -s toc -r5 --markdown man/*.ronn"
|
||||
end
|
||||
|
||||
desc "Commit the manual to git"
|
||||
task "man:commit" => :man do
|
||||
sh "git add README.markdown"
|
||||
sh "git commit -m 'update readme' || echo 'nothing to commit'"
|
||||
end
|
||||
|
||||
desc "Generate the Github docs"
|
||||
task :pages => "man:commit" do
|
||||
sh %{
|
||||
cp man/foreman.1.html /tmp/foreman.1.html
|
||||
git checkout gh-pages
|
||||
rm ./index.html
|
||||
cp /tmp/foreman.1.html ./index.html
|
||||
git add -u index.html
|
||||
git commit -m "saving man page to github docs"
|
||||
git push origin -f gh-pages
|
||||
git checkout master
|
||||
}
|
||||
end
|
||||
|
||||
task :authors do
|
||||
authors = %x{ git log --pretty=format:"%an" | sort -u }.split("\n")
|
||||
puts authors.join(", ")
|
||||
end
|
||||
|
||||
## dist
|
||||
|
||||
require "erb"
|
||||
require "fileutils"
|
||||
require "tmpdir"
|
||||
|
||||
def assemble(source, target, perms=0644)
|
||||
FileUtils.mkdir_p(File.dirname(target))
|
||||
File.open(target, "w") do |f|
|
||||
f.puts ERB.new(File.read(source)).result(binding)
|
||||
end
|
||||
File.chmod(perms, target)
|
||||
end
|
||||
|
||||
def assemble_distribution(target_dir=Dir.pwd)
|
||||
distribution_files.each do |source|
|
||||
target = source.gsub(/^#{project_root}/, target_dir)
|
||||
FileUtils.mkdir_p(File.dirname(target))
|
||||
FileUtils.cp(source, target)
|
||||
end
|
||||
end
|
||||
|
||||
GEM_BLACKLIST = %w( bundler foreman )
|
||||
|
||||
def assemble_gems(target_dir=Dir.pwd)
|
||||
lines = %x{ bundle show }.strip.split("\n")
|
||||
raise "error running bundler" unless $?.success?
|
||||
|
||||
%x{ env BUNDLE_WITHOUT="development:test" bundle show }.split("\n").each do |line|
|
||||
if line =~ /^ \* (.*?) \((.*?)\)/
|
||||
next if GEM_BLACKLIST.include?($1)
|
||||
puts "vendoring: #{$1}-#{$2}"
|
||||
gem_dir = %x{ bundle show #{$1} }.strip
|
||||
FileUtils.mkdir_p "#{target_dir}/vendor/gems"
|
||||
%x{ cp -R "#{gem_dir}" "#{target_dir}/vendor/gems" }
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
def beta?
|
||||
Foreman::VERSION.to_s =~ /pre/
|
||||
end
|
||||
|
||||
def clean(file)
|
||||
rm file if File.exists?(file)
|
||||
end
|
||||
|
||||
def distribution_files(type=nil)
|
||||
require "foreman/distribution"
|
||||
base_files = Foreman::Distribution.files
|
||||
type_files = type ?
|
||||
Dir[File.expand_path("../dist/resources/#{type}/**/*", __FILE__)] :
|
||||
[]
|
||||
base_files.concat(type_files)
|
||||
end
|
||||
|
||||
def mkchdir(dir)
|
||||
FileUtils.mkdir_p(dir)
|
||||
Dir.chdir(dir) do |dir|
|
||||
yield(File.expand_path(dir))
|
||||
end
|
||||
end
|
||||
|
||||
def pkg(filename)
|
||||
File.expand_path("../pkg/#{filename}", __FILE__)
|
||||
end
|
||||
|
||||
def project_root
|
||||
File.dirname(__FILE__)
|
||||
end
|
||||
|
||||
def resource(name)
|
||||
File.expand_path("../dist/resources/#{name}", __FILE__)
|
||||
end
|
||||
|
||||
def s3_connect
|
||||
return if @s3_connected
|
||||
|
||||
require "aws/s3"
|
||||
|
||||
unless ENV["DAVID_RELEASE_ACCESS"] && ENV["DAVID_RELEASE_SECRET"]
|
||||
puts "please set DAVID_RELEASE_ACCESS and DAVID_RELEASE_SECRET in your environment"
|
||||
exit 1
|
||||
end
|
||||
|
||||
AWS::S3::Base.establish_connection!(
|
||||
:access_key_id => ENV["DAVID_RELEASE_ACCESS"],
|
||||
:secret_access_key => ENV["DAVID_RELEASE_SECRET"]
|
||||
)
|
||||
|
||||
@s3_connected = true
|
||||
end
|
||||
|
||||
def store(package_file, filename, bucket="assets.foreman.io")
|
||||
s3_connect
|
||||
puts "storing: #{filename}"
|
||||
AWS::S3::S3Object.store(filename, File.open(package_file), bucket, :access => :public_read)
|
||||
end
|
||||
|
||||
def tempdir
|
||||
Dir.mktmpdir do |dir|
|
||||
Dir.chdir(dir) do
|
||||
yield(dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def version
|
||||
require "foreman/version"
|
||||
Foreman::VERSION
|
||||
end
|
||||
|
||||
Dir[File.expand_path("../dist/**/*.rake", __FILE__)].each do |rake|
|
||||
import rake
|
||||
end
|
||||
|
||||
task :changelog do
|
||||
timestamp = Time.now.utc.strftime('%m/%d/%Y')
|
||||
sha = `git log | head -1`.split(' ').last
|
||||
changelog = ["#{version} #{timestamp} #{sha}"]
|
||||
changelog << ('=' * changelog[0].length)
|
||||
changelog << ''
|
||||
|
||||
last_sha = `cat Changelog | head -1`.split(' ').last
|
||||
shortlog = `git log #{last_sha}..HEAD --pretty=format:'%s [%an]'`
|
||||
changelog << shortlog.split("\n")
|
||||
changelog.concat ['', '', '']
|
||||
|
||||
old_changelog = File.read('Changelog')
|
||||
File.open('Changelog', 'w') do |file|
|
||||
file.write(changelog.join("\n"))
|
||||
file.write(old_changelog)
|
||||
end
|
||||
Dir[File.expand_path("../tasks/*.rake", __FILE__)].each do |task|
|
||||
load task
|
||||
end
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Autotest.add_discovery { "rspec2" }
|
||||
@@ -1,2 +1,3 @@
|
||||
ticker: ruby ./ticker $PORT
|
||||
error: ruby ./error
|
||||
utf8: ruby ./utf8
|
||||
|
||||
11
data/example/utf8
Executable file
11
data/example/utf8
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env ruby
|
||||
# encoding: BINARY
|
||||
|
||||
$stdout.sync = true
|
||||
|
||||
while true
|
||||
puts "\u65e5\u672c\u8a9e\u6587\u5b57\u5217"
|
||||
puts "\u0915\u0932\u094d\u0907\u0928\u0643\u0637\u0628\u041a\u0430\u043b\u0438\u043d\u0430"
|
||||
puts "\xff\x03"
|
||||
sleep 1
|
||||
end
|
||||
15
dist/deb.rake
vendored
15
dist/deb.rake
vendored
@@ -20,12 +20,6 @@ file pkg("/apt-#{version}/foreman-#{version}.deb") => distribution_files("deb")
|
||||
deb = File.basename(t.name)
|
||||
|
||||
sh "ar -r #{t.name} debian-binary control.tar.gz data.tar.gz"
|
||||
|
||||
touch "Sources"
|
||||
sh "apt-ftparchive packages . > Packages"
|
||||
sh "gzip -c Packages > Packages.gz"
|
||||
sh "apt-ftparchive release . > Release"
|
||||
sh "gpg -abs -u 0F1B0520 -o Release.gpg Release"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,12 +31,3 @@ task "deb:clean" do
|
||||
clean pkg("foreman-#{version}.deb")
|
||||
FileUtils.rm_rf("pkg/apt-#{version}") if Dir.exists?("pkg/apt-#{version}")
|
||||
end
|
||||
|
||||
desc "Publish .deb to S3."
|
||||
task "deb:release" => "deb:build" do |t|
|
||||
Dir["pkg/apt-#{version}/*"].each do |file|
|
||||
unless File.directory?(file)
|
||||
store file, "apt/#{File.basename(file)}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -40,22 +40,11 @@ class Foreman::CLI < Thor
|
||||
method_option :port, :type => :numeric, :aliases => "-p"
|
||||
method_option :user, :type => :string, :aliases => "-u"
|
||||
method_option :template, :type => :string, :aliases => "-t"
|
||||
method_option :concurrency, :type => :string, :aliases => "-c",
|
||||
:banner => '"alpha=5,bar=3"'
|
||||
method_option :concurrency, :type => :string, :aliases => "-c", :banner => '"alpha=5,bar=3"'
|
||||
|
||||
def export(format, location=nil)
|
||||
check_procfile!
|
||||
|
||||
begin
|
||||
require "foreman/export/#{ format.tr('-', '_') }"
|
||||
classy_format = classify(format)
|
||||
formatter = constantize("Foreman::Export::#{ classy_format }")
|
||||
rescue NameError => ex
|
||||
error "Unknown export format: #{format} (no class Foreman::Export::#{ classy_format })."
|
||||
rescue LoadError => ex
|
||||
error "Unknown export format: #{format} (unable to load file 'foreman/export/#{ format.tr('-', '_') }')."
|
||||
end
|
||||
|
||||
formatter = Foreman::Export.formatter(format)
|
||||
formatter.new(location, engine, options).export
|
||||
rescue Foreman::Export::Exception => ex
|
||||
error ex.message
|
||||
@@ -65,7 +54,7 @@ class Foreman::CLI < Thor
|
||||
|
||||
def check
|
||||
error "no processes defined" unless engine.procfile.entries.length > 0
|
||||
display "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
||||
puts "valid procfile detected (#{engine.procfile.process_names.join(', ')})"
|
||||
end
|
||||
|
||||
desc "run COMMAND", "Run a command using your application's environment"
|
||||
@@ -95,19 +84,11 @@ private ######################################################################
|
||||
options[:procfile] || "Procfile"
|
||||
end
|
||||
|
||||
def display(message)
|
||||
puts message
|
||||
end
|
||||
|
||||
def error(message)
|
||||
puts "ERROR: #{message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
def procfile_exists?(procfile)
|
||||
File.exist?(procfile)
|
||||
end
|
||||
|
||||
def options
|
||||
original_options = super
|
||||
return original_options unless File.exists?(".foreman")
|
||||
|
||||
@@ -58,7 +58,7 @@ private ######################################################################
|
||||
concurrency = Foreman::Utils.parse_concurrency(@options[:concurrency])
|
||||
|
||||
procfile.entries.each do |entry|
|
||||
reader, writer = IO.pipe
|
||||
reader, writer = (IO.method(:pipe).arity == 0 ? IO.pipe : IO.pipe("BINARY"))
|
||||
entry.spawn(concurrency[entry.name], writer, @directory, @environment, port_for(entry, 1, base_port)).each do |process|
|
||||
running_processes[process.pid] = process
|
||||
readers[process] = reader
|
||||
@@ -78,27 +78,39 @@ private ######################################################################
|
||||
end
|
||||
|
||||
def terminate_gracefully
|
||||
return if @terminating
|
||||
@terminating = true
|
||||
info "sending SIGTERM to all processes"
|
||||
kill_all "SIGTERM"
|
||||
Timeout.timeout(5) { Process.waitall }
|
||||
Timeout.timeout(5) do
|
||||
while running_processes.length > 0
|
||||
pid, status = Process.wait2
|
||||
process = running_processes.delete(pid)
|
||||
info "process terminated", process.name
|
||||
end
|
||||
end
|
||||
rescue Timeout::Error
|
||||
info "sending SIGKILL to all processes"
|
||||
kill_all "SIGKILL"
|
||||
end
|
||||
|
||||
def poll_readers
|
||||
rs, ws = IO.select(readers.values, [], [], 1)
|
||||
(rs || []).each do |r|
|
||||
data = r.gets
|
||||
next unless data
|
||||
ps, message = data.split(",", 2)
|
||||
color = colors[ps.split(".").first]
|
||||
info message, ps, color
|
||||
end
|
||||
end
|
||||
|
||||
def watch_for_output
|
||||
Thread.new do
|
||||
require "win32console" if Foreman.windows?
|
||||
begin
|
||||
loop do
|
||||
rs, ws = IO.select(readers.values, [], [], 1)
|
||||
(rs || []).each do |r|
|
||||
data = r.gets
|
||||
next unless data
|
||||
ps, message = data.split(",", 2)
|
||||
color = colors[ps.split(".").first]
|
||||
info message, ps, color
|
||||
end
|
||||
poll_readers
|
||||
end
|
||||
rescue Exception => ex
|
||||
puts ex.message
|
||||
@@ -112,16 +124,16 @@ private ######################################################################
|
||||
process = running_processes.delete(pid)
|
||||
info "process terminated", process.name
|
||||
terminate_gracefully
|
||||
kill_all
|
||||
rescue Errno::ECHILD
|
||||
end
|
||||
|
||||
def info(message, name="system", color=Term::ANSIColor.white)
|
||||
print color
|
||||
print "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
||||
print Term::ANSIColor.reset
|
||||
print message.chomp
|
||||
puts ""
|
||||
output = ""
|
||||
output += color
|
||||
output += "#{Time.now.strftime("%H:%M:%S")} #{pad_process_name(name)} | "
|
||||
output += Term::ANSIColor.reset
|
||||
output += message.chomp
|
||||
puts output
|
||||
end
|
||||
|
||||
def print(message=nil)
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
require "foreman"
|
||||
require "foreman/helpers"
|
||||
|
||||
module Foreman::Export
|
||||
extend Foreman::Helpers
|
||||
|
||||
class Exception < ::Exception; end
|
||||
|
||||
def self.formatter(format)
|
||||
begin
|
||||
require "foreman/export/#{ format.tr('-', '_') }"
|
||||
classy_format = classify(format)
|
||||
formatter = constantize("Foreman::Export::#{ classy_format }")
|
||||
rescue NameError => ex
|
||||
error "Unknown export format: #{format} (no class Foreman::Export::#{ classy_format })."
|
||||
rescue LoadError => ex
|
||||
error "Unknown export format: #{format} (unable to load file 'foreman/export/#{ format.tr('-', '_') }')."
|
||||
end
|
||||
end
|
||||
|
||||
def self.error(message)
|
||||
raise Foreman::Export::Exception.new(message)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
require "foreman/export/base"
|
||||
require "foreman/export/inittab"
|
||||
require "foreman/export/upstart"
|
||||
|
||||
@@ -24,12 +24,12 @@ class Foreman::Export::Inittab < Foreman::Export::Base
|
||||
|
||||
inittab = inittab.join("\n") + "\n"
|
||||
|
||||
if fname
|
||||
if location == "-"
|
||||
puts inittab
|
||||
else
|
||||
FileUtils.mkdir_p(log_root) rescue error "could not create #{log_root}"
|
||||
FileUtils.chown(user, nil, log_root) rescue error "could not chown #{log_root} to #{user}"
|
||||
write_file(fname, inittab)
|
||||
else
|
||||
puts inittab
|
||||
write_file(location, inittab)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@ module Foreman::Helpers
|
||||
# classify('job-name') # => 'JobName'
|
||||
def classify(dashed_word)
|
||||
dashed_word.split('-').each { |part| part[0] = part[0].chr.upcase }.join
|
||||
end
|
||||
end # Tries to find a constant with the name specified in the argument string:
|
||||
|
||||
# Tries to find a constant with the name specified in the argument string:
|
||||
#
|
||||
# constantize("Module") # => Module
|
||||
# constantize("Test::Unit") # => Test::Unit
|
||||
@@ -28,10 +27,6 @@ module Foreman::Helpers
|
||||
def constantize(camel_cased_word)
|
||||
camel_cased_word = camel_cased_word.to_s
|
||||
|
||||
if camel_cased_word.include?('-')
|
||||
camel_cased_word = classify(camel_cased_word)
|
||||
end
|
||||
|
||||
names = camel_cased_word.split('::')
|
||||
names.shift if names.empty? || names.first.empty?
|
||||
|
||||
@@ -47,4 +42,4 @@ module Foreman::Helpers
|
||||
end
|
||||
constant
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -63,7 +63,7 @@ private
|
||||
$stderr.reopen writer
|
||||
reader.close
|
||||
exec Foreman.runner, "-d", basedir, command
|
||||
end
|
||||
end
|
||||
end
|
||||
[ reader, pid ]
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module Foreman
|
||||
|
||||
VERSION = "0.37.0.pre5"
|
||||
VERSION = "0.37.1"
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "FOREMAN" "1" "January 2012" "Foreman 0.33.1" "Foreman Manual"
|
||||
.TH "FOREMAN" "1" "January 2012" "Foreman 0.37.0" "Foreman Manual"
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBforeman\fR \- manage Procfile\-based applications
|
||||
|
||||
@@ -27,6 +27,15 @@ describe "Foreman::CLI", :fakefs do
|
||||
|
||||
describe "export" do
|
||||
describe "options" do
|
||||
it "uses .foreman" do
|
||||
write_procfile
|
||||
File.open(".foreman", "w") { |f| f.puts "concurrency: alpha=2" }
|
||||
mock_export = mock(Foreman::Export::Upstart)
|
||||
mock(Foreman::Export::Upstart).new("/upstart", is_a(Foreman::Engine), { "concurrency" => "alpha=2" }) { mock_export }
|
||||
mock_export.export
|
||||
foreman %{ export upstart /upstart }
|
||||
end
|
||||
|
||||
it "respects --env" do
|
||||
write_procfile
|
||||
write_env("envfile")
|
||||
@@ -49,10 +58,18 @@ describe "Foreman::CLI", :fakefs do
|
||||
describe "with a Procfile" do
|
||||
before(:each) { write_procfile }
|
||||
|
||||
describe "with an invalid formatter" do
|
||||
describe "with a formatter with a generic error" do
|
||||
before do
|
||||
mock(Foreman::Export).formatter("errorful") { Class.new(Foreman::Export::Base) do
|
||||
def export
|
||||
raise Foreman::Export::Exception.new("foo")
|
||||
end
|
||||
end }
|
||||
end
|
||||
|
||||
it "prints an error" do
|
||||
mock_error(subject, "Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
|
||||
subject.export("invalidformatter")
|
||||
mock_error(subject, "foo") do
|
||||
subject.export("errorful")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -76,7 +93,7 @@ describe "Foreman::CLI", :fakefs do
|
||||
before { write_procfile }
|
||||
|
||||
it "displays the jobs" do
|
||||
mock(subject).display("valid procfile detected (alpha, bravo)")
|
||||
mock(subject).puts("valid procfile detected (alpha, bravo)")
|
||||
subject.check
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,4 +83,23 @@ describe "Foreman::Engine", :fakefs do
|
||||
engine.start
|
||||
end
|
||||
end
|
||||
|
||||
describe "utf8" do
|
||||
before(:each) do
|
||||
File.open("Procfile", "w") do |file|
|
||||
file.puts "utf8: #{resource_path("bin/utf8")}"
|
||||
end
|
||||
end
|
||||
|
||||
it "should spawn" do
|
||||
stub(subject).watch_for_output
|
||||
stub(subject).watch_for_termination
|
||||
subject.start
|
||||
sleep 1
|
||||
mock(subject).info(/started with pid \d+/, "utf8.1", anything)
|
||||
mock(subject).info("\xff\x03\n", "utf8.1", anything)
|
||||
subject.send(:poll_readers)
|
||||
subject.send(:poll_readers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
22
spec/foreman/export/base_spec.rb
Normal file
22
spec/foreman/export/base_spec.rb
Normal file
@@ -0,0 +1,22 @@
|
||||
require "spec_helper"
|
||||
require "foreman/export/base"
|
||||
|
||||
describe "Foreman::Export::Base" do
|
||||
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
||||
let(:location) { "/tmp/init" }
|
||||
let(:engine) { Foreman::Engine.new(procfile) }
|
||||
let(:subject) { Foreman::Export::Base.new(location, engine) }
|
||||
|
||||
it "has a say method for displaying info" do
|
||||
mock(subject).puts("[foreman export] foo")
|
||||
subject.send(:say, "foo")
|
||||
end
|
||||
|
||||
it "export needs to be overridden" do
|
||||
lambda { subject.export }.should raise_error("export method must be overridden")
|
||||
end
|
||||
|
||||
it "raises errors as a Foreman::Export::Exception" do
|
||||
lambda { subject.send(:error, "foo") }.should raise_error(Foreman::Export::Exception, "foo")
|
||||
end
|
||||
end
|
||||
@@ -17,7 +17,14 @@ describe Foreman::Export::Bluepill, :fakefs do
|
||||
normalize_space(File.read("/tmp/init/app.pill")).should == normalize_space(example_export_file("bluepill/app.pill"))
|
||||
end
|
||||
|
||||
context "with concurrency" do
|
||||
it "cleans up if exporting into an existing dir" do
|
||||
mock(FileUtils).rm("/tmp/init/app.pill")
|
||||
|
||||
bluepill.export
|
||||
bluepill.export
|
||||
end
|
||||
|
||||
context "with concurrency" do
|
||||
let(:options) { Hash[:concurrency => "alpha=2"] }
|
||||
|
||||
it "exports to the filesystem with concurrency" do
|
||||
|
||||
40
spec/foreman/export/inittab_spec.rb
Normal file
40
spec/foreman/export/inittab_spec.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
require "spec_helper"
|
||||
require "foreman/engine"
|
||||
require "foreman/export/inittab"
|
||||
require "tmpdir"
|
||||
|
||||
describe Foreman::Export::Inittab, :fakefs do
|
||||
let(:location) { "/tmp/inittab" }
|
||||
let(:procfile) { FileUtils.mkdir_p("/tmp/app"); write_procfile("/tmp/app/Procfile") }
|
||||
let(:location) { "/tmp/inittab" }
|
||||
let(:engine) { Foreman::Engine.new(procfile) }
|
||||
let(:options) { Hash.new }
|
||||
let(:inittab) { Foreman::Export::Inittab.new(location, engine, options) }
|
||||
|
||||
before(:each) { load_export_templates_into_fakefs("inittab") }
|
||||
before(:each) { stub(inittab).say }
|
||||
|
||||
it "exports to the filesystem" do
|
||||
inittab.export
|
||||
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.default")
|
||||
end
|
||||
|
||||
context "to stdout" do
|
||||
let(:location) { "-" }
|
||||
|
||||
it "exports to stdout" do
|
||||
mock(inittab).puts example_export_file("inittab/inittab.default")
|
||||
inittab.export
|
||||
end
|
||||
end
|
||||
|
||||
context "with concurrency" do
|
||||
let(:options) { Hash[:concurrency => "alpha=2"] }
|
||||
|
||||
it "exports to the filesystem with concurrency" do
|
||||
inittab.export
|
||||
File.read("/tmp/inittab").should == example_export_file("inittab/inittab.concurrency")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -22,6 +22,17 @@ describe Foreman::Export::Upstart, :fakefs do
|
||||
File.read("/tmp/init/app-bravo-1.conf").should == example_export_file("upstart/app-bravo-1.conf")
|
||||
end
|
||||
|
||||
it "cleans up if exporting into an existing dir" do
|
||||
mock(FileUtils).rm("/tmp/init/app.conf")
|
||||
mock(FileUtils).rm("/tmp/init/app-alpha.conf")
|
||||
mock(FileUtils).rm("/tmp/init/app-alpha-1.conf")
|
||||
mock(FileUtils).rm("/tmp/init/app-bravo.conf")
|
||||
mock(FileUtils).rm("/tmp/init/app-bravo-1.conf")
|
||||
|
||||
upstart.export
|
||||
upstart.export
|
||||
end
|
||||
|
||||
context "with concurrency" do
|
||||
let(:options) { Hash[:concurrency => "alpha=2"] }
|
||||
|
||||
|
||||
@@ -1,2 +1,24 @@
|
||||
require "spec_helper"
|
||||
require "foreman/export"
|
||||
|
||||
describe "Foreman::Export" do
|
||||
subject { Foreman::Export }
|
||||
|
||||
describe "with a formatter that doesn't declare the appropriate class" do
|
||||
it "prints an error" do
|
||||
mock(subject).require("foreman/export/invalidformatter")
|
||||
mock_export_error("Unknown export format: invalidformatter (no class Foreman::Export::Invalidformatter).") do
|
||||
subject.formatter("invalidformatter")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "with an invalid formatter" do
|
||||
|
||||
it "prints an error" do
|
||||
mock_export_error("Unknown export format: invalidformatter (unable to load file 'foreman/export/invalidformatter').") do
|
||||
subject.formatter("invalidformatter")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
26
spec/foreman/helpers_spec.rb
Normal file
26
spec/foreman/helpers_spec.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
require "spec_helper"
|
||||
require "foreman/helpers"
|
||||
|
||||
describe "Foreman::Helpers" do
|
||||
before do
|
||||
module Foo
|
||||
class Bar; end
|
||||
end
|
||||
end
|
||||
|
||||
after do
|
||||
Object.send(:remove_const, :Foo)
|
||||
end
|
||||
|
||||
subject { o = Object.new; o.extend(Foreman::Helpers); o }
|
||||
|
||||
it "should classify words" do
|
||||
subject.classify("foo").should == "Foo"
|
||||
subject.classify("foo-bar").should == "FooBar"
|
||||
end
|
||||
|
||||
it "should constantize words" do
|
||||
subject.constantize("Object").should == Object
|
||||
subject.constantize("Foo::Bar").should == Foo::Bar
|
||||
end
|
||||
end
|
||||
@@ -36,6 +36,7 @@ describe Foreman::Process do
|
||||
def run_file(executable, code)
|
||||
file = File.open("#{basedir}/script", 'w') {|it| it << code }
|
||||
run "#{executable} #{file.path}"
|
||||
sleep 1
|
||||
end
|
||||
|
||||
context 'options' do
|
||||
@@ -98,7 +99,6 @@ describe Foreman::Process do
|
||||
trap "TERM", "IGNORE"
|
||||
loop { sleep 1 }
|
||||
CODE
|
||||
sleep 1 # wait for ruby to start
|
||||
subject.should be_alive
|
||||
subject.kill 'TERM'
|
||||
subject.should be_alive
|
||||
|
||||
@@ -25,4 +25,10 @@ describe Foreman do
|
||||
ENV['FOO'].should == 'bar'
|
||||
end
|
||||
end
|
||||
|
||||
describe "runner" do
|
||||
it "should exist" do
|
||||
File.exists?(Foreman.runner).should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
2
spec/resources/bin/utf8
Executable file
2
spec/resources/bin/utf8
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env ruby
|
||||
puts "\xff\x03"
|
||||
4
spec/resources/export/inittab/inittab.concurrency
Normal file
4
spec/resources/export/inittab/inittab.concurrency
Normal file
@@ -0,0 +1,4 @@
|
||||
# ----- foreman app processes -----
|
||||
AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
|
||||
AP02:4:respawn:/bin/su - app -c 'PORT=5001 ./alpha >> /var/log/app/alpha-2.log 2>&1'
|
||||
# ----- end foreman app processes -----
|
||||
4
spec/resources/export/inittab/inittab.default
Normal file
4
spec/resources/export/inittab/inittab.default
Normal file
@@ -0,0 +1,4 @@
|
||||
# ----- foreman app processes -----
|
||||
AP01:4:respawn:/bin/su - app -c 'PORT=5000 ./alpha >> /var/log/app/alpha-1.log 2>&1'
|
||||
AP02:4:respawn:/bin/su - app -c 'PORT=5100 ./bravo >> /var/log/app/bravo-1.log 2>&1'
|
||||
# ----- end foreman app processes -----
|
||||
@@ -1,10 +1,20 @@
|
||||
require "rubygems"
|
||||
|
||||
require "simplecov"
|
||||
SimpleCov.start do
|
||||
add_filter "/spec/"
|
||||
end
|
||||
|
||||
require "rspec"
|
||||
require "fakefs/safe"
|
||||
require "fakefs/spec_helpers"
|
||||
|
||||
$:.unshift File.expand_path("../../lib", __FILE__)
|
||||
|
||||
def mock_export_error(message)
|
||||
lambda { yield }.should raise_error(Foreman::Export::Exception, message)
|
||||
end
|
||||
|
||||
def mock_error(subject, message)
|
||||
mock_exit do
|
||||
mock(subject).puts("ERROR: #{message}")
|
||||
@@ -37,9 +47,11 @@ def write_procfile(procfile="Procfile", alpha_env="")
|
||||
File.expand_path(procfile)
|
||||
end
|
||||
|
||||
def write_env(env=".env")
|
||||
def write_env(env=".env", options={"FOO"=>"bar"})
|
||||
File.open(env, "w") do |file|
|
||||
file.puts "FOO=bar"
|
||||
options.each do |key, val|
|
||||
file.puts "#{key}=#{val}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -56,9 +68,13 @@ def load_export_templates_into_fakefs(type)
|
||||
end
|
||||
end
|
||||
|
||||
def resource_path(filename)
|
||||
File.expand_path("../resources/#{filename}", __FILE__)
|
||||
end
|
||||
|
||||
def example_export_file(filename)
|
||||
FakeFS.deactivate!
|
||||
data = File.read(File.expand_path("../resources/export/#{filename}", __FILE__))
|
||||
data = File.read(File.expand_path(resource_path("export/#{filename}"), __FILE__))
|
||||
FakeFS.activate!
|
||||
data
|
||||
end
|
||||
|
||||
112
tasks/dist.rake
Normal file
112
tasks/dist.rake
Normal file
@@ -0,0 +1,112 @@
|
||||
require "erb"
|
||||
require "fileutils"
|
||||
require "tmpdir"
|
||||
|
||||
def assemble(source, target, perms=0644)
|
||||
FileUtils.mkdir_p(File.dirname(target))
|
||||
File.open(target, "w") do |f|
|
||||
f.puts ERB.new(File.read(source)).result(binding)
|
||||
end
|
||||
File.chmod(perms, target)
|
||||
end
|
||||
|
||||
def assemble_distribution(target_dir=Dir.pwd)
|
||||
distribution_files.each do |source|
|
||||
target = source.gsub(/^#{project_root}/, target_dir)
|
||||
FileUtils.mkdir_p(File.dirname(target))
|
||||
FileUtils.cp(source, target)
|
||||
end
|
||||
end
|
||||
|
||||
GEM_BLACKLIST = %w( bundler foreman )
|
||||
|
||||
def assemble_gems(target_dir=Dir.pwd)
|
||||
lines = %x{ cd #{project_root} && bundle show }.strip.split("\n")
|
||||
raise "error running bundler" unless $?.success?
|
||||
|
||||
%x{ env BUNDLE_WITHOUT="development:test" bundle show }.split("\n").each do |line|
|
||||
if line =~ /^ \* (.*?) \((.*?)\)/
|
||||
next if GEM_BLACKLIST.include?($1)
|
||||
puts "vendoring: #{$1}-#{$2}"
|
||||
gem_dir = %x{ bundle show #{$1} }.strip
|
||||
FileUtils.mkdir_p "#{target_dir}/vendor/gems"
|
||||
%x{ cp -R "#{gem_dir}" "#{target_dir}/vendor/gems" }
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
def beta?
|
||||
Foreman::VERSION.to_s =~ /pre/
|
||||
end
|
||||
|
||||
def clean(file)
|
||||
rm file if File.exists?(file)
|
||||
end
|
||||
|
||||
def distribution_files(type=nil)
|
||||
require "foreman/distribution"
|
||||
base_files = Foreman::Distribution.files
|
||||
type_files = type ?
|
||||
Dir[File.expand_path("../../dist/resources/#{type}/**/*", __FILE__)] : []
|
||||
base_files.concat(type_files)
|
||||
end
|
||||
|
||||
def mkchdir(dir)
|
||||
FileUtils.mkdir_p(dir)
|
||||
Dir.chdir(dir) do |dir|
|
||||
yield(File.expand_path(dir))
|
||||
end
|
||||
end
|
||||
|
||||
def pkg(filename)
|
||||
File.expand_path("../../pkg/#{filename}", __FILE__)
|
||||
end
|
||||
|
||||
def project_root
|
||||
File.expand_path("../..", __FILE__)
|
||||
end
|
||||
|
||||
def resource(name)
|
||||
File.expand_path("../../dist/resources/#{name}", __FILE__)
|
||||
end
|
||||
|
||||
def s3_connect
|
||||
return if @s3_connected
|
||||
|
||||
require "aws/s3"
|
||||
|
||||
unless ENV["DAVID_RELEASE_ACCESS"] && ENV["DAVID_RELEASE_SECRET"]
|
||||
puts "please set DAVID_RELEASE_ACCESS and DAVID_RELEASE_SECRET in your environment"
|
||||
exit 1
|
||||
end
|
||||
|
||||
AWS::S3::Base.establish_connection!(
|
||||
:access_key_id => ENV["DAVID_RELEASE_ACCESS"],
|
||||
:secret_access_key => ENV["DAVID_RELEASE_SECRET"]
|
||||
)
|
||||
|
||||
@s3_connected = true
|
||||
end
|
||||
|
||||
def store(package_file, filename, bucket="assets.foreman.io")
|
||||
s3_connect
|
||||
puts "storing: #{filename}"
|
||||
AWS::S3::S3Object.store(filename, File.open(package_file), bucket, :access => :public_read)
|
||||
end
|
||||
|
||||
def tempdir
|
||||
Dir.mktmpdir do |dir|
|
||||
Dir.chdir(dir) do
|
||||
yield(dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def version
|
||||
require "foreman/version"
|
||||
Foreman::VERSION
|
||||
end
|
||||
|
||||
Dir[File.expand_path("../../dist/**/*.rake", __FILE__)].each do |rake|
|
||||
import rake
|
||||
end
|
||||
74
tasks/release.rake
Normal file
74
tasks/release.rake
Normal file
@@ -0,0 +1,74 @@
|
||||
require "time"
|
||||
|
||||
desc "Build the manual"
|
||||
task :man do
|
||||
ENV['RONN_MANUAL'] = "Foreman Manual"
|
||||
ENV['RONN_ORGANIZATION'] = "Foreman #{Foreman::VERSION}"
|
||||
sh "ronn -w -s toc -r5 --markdown man/*.ronn"
|
||||
end
|
||||
|
||||
desc "Commit the manual to git"
|
||||
task "man:commit" => :man do
|
||||
sh "git add README.md"
|
||||
sh "git commit -am 'update docs' || echo 'nothing to commit'"
|
||||
end
|
||||
|
||||
desc "Generate the Github docs"
|
||||
task :pages => "man:commit" do
|
||||
sh %{
|
||||
cp man/foreman.1.html /tmp/foreman.1.html
|
||||
git checkout gh-pages
|
||||
rm ./index.html
|
||||
cp /tmp/foreman.1.html ./index.html
|
||||
git add -u index.html
|
||||
git commit -m "saving man page to github docs"
|
||||
git push origin -f gh-pages
|
||||
git checkout master
|
||||
}
|
||||
end
|
||||
|
||||
desc "Generate an authors list"
|
||||
task :authors do
|
||||
authors = %x{ git log --pretty=format:"%an" | sort -u }.split("\n")
|
||||
readme = File.read("README.md")
|
||||
readme.gsub!(/#### Patches contributed by\n([^\n]*)\n/m, "#### Patches contributed by\n#{authors.join(", ")}\n")
|
||||
File.open("README.md", "w") { |f| f.print readme }
|
||||
end
|
||||
|
||||
def latest_release
|
||||
latest = File.read("Changelog.md").split("\n").first.split(" ")[1]
|
||||
end
|
||||
|
||||
def newer_release
|
||||
tags = %x{ git tag --contains v#{latest_release} }.split("\n").sort_by do |tag|
|
||||
Gem::Version.new(tag[1..-1])
|
||||
end
|
||||
tags.reject { |tag| Gem::Version.new(tag[1..-1]).prerelease? }[1]
|
||||
end
|
||||
|
||||
desc "Generate a Changelog"
|
||||
task :changelog do
|
||||
while release = newer_release
|
||||
entry = %x{ git show --format="%cd" #{release} | head -n 1 }
|
||||
date = Time.parse(entry.chomp).strftime("%Y-%m-%d")
|
||||
|
||||
message = "## #{release[1..-1]} (#{date})\n\n"
|
||||
message += %x{ git log --format="* %s [%an]" v#{latest_release}..#{release} }
|
||||
|
||||
changelog = File.read("Changelog.md")
|
||||
changelog = message + "\n" + changelog
|
||||
|
||||
puts release
|
||||
|
||||
File.open("Changelog.md", "w") do |file|
|
||||
file.print changelog
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
desc "Cut a release"
|
||||
task :release do
|
||||
Rake::Task["authors"].invoke
|
||||
Rake::Task["changelog"].invoke
|
||||
Rake::Task["pages"].invoke
|
||||
end
|
||||
8
tasks/rspec.rake
Normal file
8
tasks/rspec.rake
Normal file
@@ -0,0 +1,8 @@
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
task :default => :spec
|
||||
|
||||
desc "Run all specs"
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
t.pattern = 'spec/**/*_spec.rb'
|
||||
end
|
||||
Reference in New Issue
Block a user