rails-precompile2git 1.0.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.
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'whenever', :require => false
4
+
5
+ gem 'git', '1.2.5'
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.2.2)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ chronic (0.6.7)
8
+ git (1.2.5)
9
+ i18n (0.6.0)
10
+ multi_json (1.1.0)
11
+ whenever (0.7.3)
12
+ activesupport (>= 2.3.4)
13
+ chronic (~> 0.6.3)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ git (= 1.2.5)
20
+ whenever
data/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # Rails : Precompile 2 Git
2
+
3
+ A small lib that makes Rails 3.1.x deployments faster.
4
+
5
+ With Rails 3.1 and the assets pipeline, you may have to precompile your assets before or after deploying. Both methods have pros and cons:
6
+
7
+ - before: makes deployment as fast as before Rails 3.1, but deploy will fail if assets:precompile has not been done (which should be done by developpers)
8
+
9
+ - after (usually as a hook of a capistrano task): will add an overhead to your deployment time, and in clustered environment, it might also be run multiple times, which might not necessary
10
+
11
+ Precompile2git is a daemon that will, watch a git repo and will execute a routine for each new commit:
12
+
13
+ - break any currently running assets precompilation
14
+ - launch a new "rake assets:precompile"
15
+ - commit everything (with user_name and user_email as git config as set in config file)
16
+ - push to origin on a specific branch (as set in config file)
17
+
18
+ It makes deployments as fast as before Rails 3.1, and its secure the process.
19
+
20
+ ## Installation
21
+
22
+ Everything should be pretty straight forward:
23
+
24
+ - Copy the `precompile2git.yml.example into `YOUR_RAILS_PROJECT/config/precompile2git.yml` and customize it
25
+ - In `YOUR_RAILS_PROJECT/` folder run `precompile2git`
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rails-precompile2git"
8
+ gem.summary = %Q{Rails Assets Precompile To Git}
9
+ gem.description = %Q{Daemon that watch a Git repo for new commit, pull changes, precompile assets and push back to Git}
10
+ gem.license = "Apache 2"
11
+ gem.email = "robin.komiwes@gmail.com"
12
+ gem.homepage = "http://github.com/nectify/rails-precompile2git"
13
+ gem.authors = ["Robin Komiwes"]
14
+ gem.rubyforge_project = "rails-precompile2git"
15
+ end
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/*_test.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/*_test.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.1
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+
5
+ require "precompile2git"
6
+
7
+ p2g = Precompile2git.new
8
+ p2g.start
@@ -0,0 +1,176 @@
1
+ require 'rubygems'
2
+ require 'git'
3
+ require 'logger'
4
+ require 'process'
5
+ require 'yaml'
6
+
7
+
8
+ class Precompile2git
9
+
10
+ def initialize
11
+ @project_dir = Dir.getwd
12
+
13
+ @logger = Logger.new(STDOUT)
14
+
15
+ config = YAML.load_file(@project_dir + "/config/precompile2git.yml")
16
+ config["precompile2git"].each { |key, value| instance_variable_set("@#{key}", value) }
17
+
18
+ git_opts = @log_git ? { :log => @logger } : {}
19
+
20
+ @g = Git.open(@project_dir , git_opts)
21
+
22
+ @g.config('user.name', @user_name) if @user_name
23
+ @g.config('user.email', @user_email) if @user_email
24
+ end
25
+
26
+
27
+ # Commit and push to compiled branch
28
+ def commit_and_push
29
+ begin
30
+ @g.add('.')
31
+ @g.commit_all("Assets precompilation")
32
+ rescue Git::GitExecuteError => e
33
+ @logger.error("Could not commit. This can occur if there was nothing to commit.")
34
+ end
35
+
36
+ begin
37
+ @g.push("origin", @compiled_branch)
38
+ rescue Git::GitExecuteError => e
39
+ @logger.error("Could not push changes. Git error: " + e.inspect)
40
+ end
41
+
42
+
43
+ end
44
+
45
+
46
+ # Starts watching a git for any update and run precompilation task
47
+ def start
48
+ @logger.info("Syncing repo.")
49
+
50
+ sync_and_merge
51
+
52
+ @logger.info("Syncing done, running first precompilation.")
53
+
54
+ precompile
55
+
56
+ @logger.info("Precompilation process started, start watching.")
57
+
58
+ @watch_thread = watch_repo(5)
59
+ @watch_thread.join
60
+ end
61
+
62
+
63
+ # Creates a new processes and start the assets:precompile rake task
64
+ def precompile
65
+ begin
66
+ if @precompilation_process_pid
67
+
68
+ @logger.info("A precompilation has been launched before. Killing any rake tasks that is still running")
69
+
70
+ begin
71
+ pids = Process.descendant_processes(@precompilation_process_pid)
72
+
73
+ pids.each do |pid|
74
+ @logger.info("Killing pid:" + pid.to_s)
75
+ Process.kill(9, pid)
76
+ end
77
+ rescue Exception => e
78
+ @logger.info("Something went wrong when killing running processes: " + e.to_s)
79
+ end
80
+ end
81
+
82
+
83
+ @precompilation_process_pid = fork do
84
+ @logger.info("Precompiler: Starting assets precompilation")
85
+
86
+ system('RAILS_ENV=' + @rails_env + ' rake assets:precompile ;')
87
+
88
+ @logger.info("Precompiler: Precompilation done. Committing and pushing")
89
+
90
+ commit_and_push
91
+
92
+ @logger.info("Precompiler: Pushed to main branch. Ready to deploy!")
93
+
94
+ @precompilation_process_pid = nil
95
+ end
96
+
97
+ rescue Exception => e
98
+ @logger.info "Something went wrong in precompilation process: " + e.to_s
99
+ end
100
+ end
101
+
102
+
103
+ # Makes sure that each branch is the mirror of origin, to prevent any merging issue
104
+ def sync_with_origin( branch_name )
105
+ locals = @g.branches.local.map{ |b| b.to_s }
106
+
107
+ @g.reset_hard
108
+
109
+ if locals.include?(branch_name)
110
+ @g.checkout(branch_name)
111
+ else
112
+ @g.checkout("origin/" + branch_name, { :new_branch => branch_name } )
113
+ end
114
+
115
+ @g.reset_hard("origin/" + branch_name)
116
+ @g.pull("origin", branch_name)
117
+ end
118
+
119
+
120
+ # Resets both compiled and uncompiled branch to have mirror of origin
121
+ # Then merges uncompiled_branch to compiled one
122
+ def sync_and_merge
123
+ sync_with_origin(@uncompiled_branch)
124
+ sync_with_origin(@compiled_branch)
125
+
126
+ # finally merge everything, this should be
127
+ @g.merge(@uncompiled_branch, nil)
128
+ end
129
+
130
+
131
+ # Checkout the repo and check if there is any new commit in uncompiled branch
132
+ def up_to_date?
133
+ begin
134
+ @g.fetch
135
+
136
+ # logs should be empty if no updates
137
+ log = @g.log.between(@uncompiled_branch, "origin/" + @uncompiled_branch)
138
+
139
+ return log.size == 0
140
+
141
+ rescue Exception => e
142
+ @logger.error("Could not check repository state. ")
143
+ return true
144
+ end
145
+ end
146
+
147
+
148
+ # Watch for a given interval if the repo has been updated.
149
+ # If so, any running rake task should be killed and a new ones should be launched
150
+ def watch_repo(interval)
151
+ Thread.new do
152
+ loop do
153
+ start_time = Time.now
154
+
155
+ begin
156
+ up_to_date = up_to_date?
157
+
158
+ unless up_to_date
159
+ @logger.info("New commits found, precompiling.")
160
+
161
+ sync_and_merge
162
+
163
+ precompile
164
+ end
165
+
166
+ rescue Git::GitExecuteError => e
167
+ @logger.error("Something went wrong with Git : " + e.to_s)
168
+ end
169
+
170
+ elapsed = Time.now - start_time
171
+ sleep( [ interval - elapsed, 0].max )
172
+ end
173
+ end
174
+ end
175
+
176
+ end
data/lib/process.rb ADDED
@@ -0,0 +1,8 @@
1
+ # from: http://t-a-w.blogspot.fr/2010/04/how-to-kill-all-your-children.html
2
+ def Process.descendant_processes(base = Process.pid)
3
+ descendants = Hash.new{|ht,k| ht[k]=[k]}
4
+ Hash[*`ps -eo pid,ppid`.scan(/\d+/).map{|x|x.to_i}].each{|pid,ppid|
5
+ descendants[ppid] << descendants[pid]
6
+ }
7
+ descendants[base].flatten - [base]
8
+ end
@@ -0,0 +1,6 @@
1
+ precompile2git:
2
+ uncompiled_branch: master-launchpad
3
+ compiled_branch: master
4
+ user_name: precompile2git
5
+ user_email: team@fre.sc
6
+ rails_env: production
@@ -0,0 +1,52 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "rails-precompile2git"
8
+ s.version = "1.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Robin Komiwes"]
12
+ s.date = "2012-03-27"
13
+ s.description = "Daemon that watch a Git repo for new commit, pull changes, precompile assets and push back to Git"
14
+ s.email = "robin.komiwes@gmail.com"
15
+ s.executables = ["precompile2git"]
16
+ s.extra_rdoc_files = [
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "README.md",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "bin/precompile2git",
26
+ "lib/precompile2git.rb",
27
+ "lib/process.rb",
28
+ "precompile2git.yml.example"
29
+ ]
30
+ s.homepage = "http://github.com/nectify/rails-precompile2git"
31
+ s.licenses = ["Apache 2"]
32
+ s.require_paths = ["lib"]
33
+ s.rubyforge_project = "rails-precompile2git"
34
+ s.rubygems_version = "1.8.21"
35
+ s.summary = "Rails Assets Precompile To Git"
36
+
37
+ if s.respond_to? :specification_version then
38
+ s.specification_version = 3
39
+
40
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
41
+ s.add_runtime_dependency(%q<whenever>, [">= 0"])
42
+ s.add_runtime_dependency(%q<git>, ["= 1.2.5"])
43
+ else
44
+ s.add_dependency(%q<whenever>, [">= 0"])
45
+ s.add_dependency(%q<git>, ["= 1.2.5"])
46
+ end
47
+ else
48
+ s.add_dependency(%q<whenever>, [">= 0"])
49
+ s.add_dependency(%q<git>, ["= 1.2.5"])
50
+ end
51
+ end
52
+
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-precompile2git
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Robin Komiwes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: whenever
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: git
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.2.5
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.2.5
46
+ description: Daemon that watch a Git repo for new commit, pull changes, precompile
47
+ assets and push back to Git
48
+ email: robin.komiwes@gmail.com
49
+ executables:
50
+ - precompile2git
51
+ extensions: []
52
+ extra_rdoc_files:
53
+ - README.md
54
+ files:
55
+ - Gemfile
56
+ - Gemfile.lock
57
+ - README.md
58
+ - Rakefile
59
+ - VERSION
60
+ - bin/precompile2git
61
+ - lib/precompile2git.rb
62
+ - lib/process.rb
63
+ - precompile2git.yml.example
64
+ - rails-precompile2git.gemspec
65
+ homepage: http://github.com/nectify/rails-precompile2git
66
+ licenses:
67
+ - Apache 2
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project: rails-precompile2git
86
+ rubygems_version: 1.8.21
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Rails Assets Precompile To Git
90
+ test_files: []