blazing 0.0.1 → 0.0.2

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 CHANGED
@@ -2,3 +2,6 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in blazing.gemspec
4
4
  gemspec
5
+
6
+ gem 'rspec'
7
+ gem 'ruby-debug19'
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ blazing (0.0.1)
5
+ thor (>= 0.14.6)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ archive-tar-minitar (0.5.2)
11
+ columnize (0.3.2)
12
+ diff-lcs (1.1.2)
13
+ linecache19 (0.5.11)
14
+ ruby_core_source (>= 0.1.4)
15
+ rspec (2.4.0)
16
+ rspec-core (~> 2.4.0)
17
+ rspec-expectations (~> 2.4.0)
18
+ rspec-mocks (~> 2.4.0)
19
+ rspec-core (2.4.0)
20
+ rspec-expectations (2.4.0)
21
+ diff-lcs (~> 1.1.2)
22
+ rspec-mocks (2.4.0)
23
+ ruby-debug-base19 (0.11.24)
24
+ columnize (>= 0.3.1)
25
+ linecache19 (>= 0.5.11)
26
+ ruby_core_source (>= 0.1.4)
27
+ ruby-debug19 (0.11.6)
28
+ columnize (>= 0.3.1)
29
+ linecache19 (>= 0.5.11)
30
+ ruby-debug-base19 (>= 0.11.19)
31
+ ruby_core_source (0.1.4)
32
+ archive-tar-minitar (>= 0.5.2)
33
+ thor (0.14.6)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ blazing!
40
+ rspec
41
+ ruby-debug19
42
+ thor (>= 0.14.6)
data/README CHANGED
@@ -6,6 +6,26 @@ Top Design goals, ideas:
6
6
 
7
7
  - deploy is just a push to another remote. all that must be done is triggered by pre and post receveie git hooks.
8
8
  - initial setup done by ruby script
9
- - the stuff that gets executed is defined in recipes, which are handled kind of like chef recipes with vendor branches
9
+ - extensible recipe system, so you can plug in and out what you need and easily roll your own recipes
10
10
 
11
- Also, I just wanted to play around with instance_eval and such :-)
11
+ == Usage
12
+
13
+ Setup a project with
14
+
15
+ blazing init
16
+
17
+ Then edit your config/blazing.rb file.
18
+
19
+ If you are ready to do your first deploy, run
20
+
21
+ blazing setup <target_name>
22
+
23
+ Afterwards you can just deploy with
24
+
25
+ blazing deploy <target_name>
26
+
27
+ Or just use
28
+
29
+ git push <target_name>
30
+
31
+ which does basically the same
data/TODO CHANGED
@@ -6,6 +6,4 @@ o customizable and modular
6
6
  o multistage
7
7
  o sync fs and db flavours
8
8
 
9
- o recipes should live in git submodules
10
-
11
-
9
+ o recipes should/can live in git submodules
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rubygems'
4
3
  require 'thor'
4
+ require 'thor/group'
5
5
  require 'blazing'
6
- require 'blazing/cli'
6
+ require 'blazing/cli/base'
7
7
 
8
- Blazing::CLI.start
8
+ Blazing::CLI::Base.start
@@ -8,16 +8,14 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Felipe Kaufmann"]
10
10
  s.email = ["felipekaufmann@gmail.com"]
11
- s.homepage = ""
11
+ s.homepage = "https://github.com/effkay/blazing"
12
12
  s.summary = %q{blazing fast deployment}
13
- s.description = %q{git push style deployments for the masses}
14
-
15
- s.rubyforge_project = "blazing"
16
-
13
+ s.description = %q{git push deployent utility, ready to be extended by your own recipes}
17
14
  s.files = `git ls-files`.split("\n")
18
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
17
  s.require_paths = ["lib"]
21
18
 
19
+ # TODO: better to use ~ ?
22
20
  s.add_dependency "thor", ">= 0.14.6"
23
21
  end
@@ -0,0 +1,8 @@
1
+ module Blazing
2
+ 'blazing/base'
3
+ 'blazing/cli'
4
+ 'blazing/version'
5
+ 'blazing/config'
6
+ 'blazing/remote'
7
+ 'blazing/remote'
8
+ end
@@ -1,5 +1,5 @@
1
- require 'blazing/cli'
2
1
  require 'blazing/config'
2
+ require 'blazing/cli'
3
3
 
4
4
  module Blazing::Base
5
5
 
@@ -1,4 +1,5 @@
1
1
  require 'blazing/config'
2
+ require 'blazing/config/helper'
2
3
 
3
4
  class Blazing::CLI < Thor
4
5
 
@@ -15,30 +16,26 @@ class Blazing::CLI < Thor
15
16
 
16
17
  desc 'setup TARGET', 'bootstrap or update blazing setup on remote host and do a first deploy'
17
18
  def setup(target = nil)
18
-
19
- # Load config file
20
- config = Blazing::Config.read do |blazing|
21
- blazing.instance_eval(File.read blazing.file)
22
- end
23
-
24
- # Check if target can be found in config file
25
- if target
26
- target = config.targets.find { |t| t.name == target.to_sym }
27
- end
28
-
29
- target = target || config.determine_target
19
+
20
+ target = Blazing::Config::Helper.find_target(target)
30
21
 
31
22
  if target
32
23
  say "[BLAZING] -- SETTING UP #{ target.location }", :yellow
33
- invoke 'blazing:target:setup:setup_repository', [target]
24
+ invoke 'blazing:remote:setup:setup_repository', [target]
34
25
  else
35
- say 'no target specified and no default found in config', :red
26
+ say 'no remote specified and no default found in config', :red
36
27
  end
37
28
 
38
29
  end
39
30
 
40
31
  desc 'deploy TARGET', 'deploy project with blazing'
41
- def deploy
32
+ def deploy(target=nil)
33
+
34
+ target = Blazing::Config::Helper.find_target(target)
35
+
36
+ # TODO: optional: specify branch
37
+ `git push #{ target.name } master`
38
+
42
39
  # TODO: check if deployed setup is still uptodate, if not, run setup
43
40
  # tag and push
44
41
  end
@@ -0,0 +1,73 @@
1
+ require 'thor/group'
2
+ require 'blazing/remote'
3
+
4
+ class Blazing::Config
5
+
6
+ attr_accessor :targets, :file
7
+
8
+ def initialize
9
+ @targets = []
10
+ @file = File.open('config/blazing.rb')
11
+ end
12
+
13
+ def self.read(&block)
14
+ config = Blazing::Config.new
15
+ block.arity < 1 ? config.instance_eval(&block) : block.call(config)
16
+ config.instance_eval(&block)
17
+ return config
18
+ end
19
+
20
+ def remote(name, &block)
21
+ @targets << Blazing::Target.new(name, @repository, &block)
22
+ end
23
+
24
+ def repository(url)
25
+ @repository = url
26
+ end
27
+
28
+ def determine_target
29
+ target = case
30
+ when self.targets.size == 1 && !self.targets.first.location.nil?
31
+ self.targets.first
32
+
33
+ when !self.default.default_target.nil?
34
+ self.targets.find { |t| t.name == self.default.default_target }
35
+
36
+ when self.default && !self.default.hostname.nil?
37
+ self.default
38
+ end
39
+
40
+ return target
41
+ end
42
+
43
+ def default
44
+ self.targets.find { |t| t.name == :blazing}
45
+ end
46
+
47
+ # TODO: Why does thor break when this is put into an external file config folder?
48
+ class Create < Thor::Group
49
+
50
+ desc 'creates a blazing config file'
51
+
52
+ include Thor::Actions
53
+
54
+ argument :username
55
+ argument :hostname
56
+ argument :path
57
+ argument :repository
58
+
59
+ def self.source_root
60
+ File.dirname(__FILE__)
61
+ end
62
+
63
+ def create_blazing_dir
64
+ empty_directory 'config'
65
+ end
66
+
67
+ def create_config_file
68
+ template('templates/blazing.tt', "config/blazing.rb")
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,18 @@
1
+ require 'blazing/config'
2
+
3
+ module Blazing::Config::Helper
4
+
5
+ def self.find_target(target=nil)
6
+ config = Blazing::Config.read do |blazing|
7
+ blazing.instance_eval(File.read blazing.file)
8
+ end
9
+
10
+ # Check if remote can be found in config file
11
+ if target
12
+ target = config.targets.find { |t| t.name == target.to_sym }
13
+ end
14
+
15
+ target = target || config.determine_target
16
+ end
17
+
18
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Stuff that runs on remote machine
3
+ #
4
+ class Blazing::Remote
5
+
6
+ def self.pre_receive(target_name)
7
+ # really needed? probably only for maintenance page, maybe even this can be done post receive
8
+ end
9
+
10
+ def self.post_receive(target_name)
11
+
12
+ target = Blazing::Config::Helper.find_target(target_name)
13
+
14
+ `git reset --hard HEAD`
15
+
16
+ `bundle update`
17
+ end
18
+
19
+ end
@@ -0,0 +1,86 @@
1
+ class Blazing::Target
2
+
3
+ attr_accessor :name, :user, :hostname, :path, :recipes, :target_name, :default_target, :repository
4
+
5
+ def initialize(name, repository, &block)
6
+ @name = name
7
+ @repository = repository
8
+ instance_eval &block
9
+ end
10
+
11
+ def deploy_to(location)
12
+ @user = location.match('(.*)@')[1]
13
+ @hostname = location.match('@(.*):')[1]
14
+ @path = location.match(':(.*)')[1]
15
+ end
16
+
17
+ def location
18
+ # TODO: build this together more carefully, checking for emtpy hostname etc...
19
+ @location ||= "#{ @user }@#{ @hostname }:#{ @path }"
20
+ end
21
+
22
+ # Only used in global remote for setting default remote
23
+ # TODO: extract into other class, inherit
24
+ def set_default_target(target_name)
25
+ @default_target = target_name
26
+ end
27
+
28
+ class Setup < Thor
29
+
30
+ include Thor::Actions
31
+
32
+ def self.source_root
33
+ File.dirname(__FILE__)
34
+ end
35
+
36
+ argument :target
37
+
38
+ desc 'setup:setup_repository TARGET', 'sets up a remote for blazing deployments'
39
+ def setup_repository
40
+
41
+ # TODO: Extract into helper
42
+ # remote_with_condition()
43
+
44
+ command = "if [ -e ~/sites/blazingoverride.ch/ ]; then echo 'repository has been cloned already'; else git clone #{ remote.repository } #{ remote.path } && git config receive.denyCurrentBranch ignore; fi"
45
+ system "ssh #{ remote.user }@#{ remote.hostname } '#{ command }'"
46
+ if $? == 0
47
+ say '--> [ok]', :green
48
+ invoke 'add_pre_receive_hook', remote
49
+ else
50
+ say '--> [FAILED]', :red
51
+ say '[BLAZING] -- ROLLING BACK', :blue
52
+ return
53
+ end
54
+ end
55
+
56
+ desc 'setup:clone_repository TARGET', 'sets up a remote for blazing deployments'
57
+ def add_pre_receive_hook
58
+ say 'adding pre-receive hook'
59
+ pre_hook = "deploy/pre-receive"
60
+ template('templates/pre-hook.tt', pre_hook)
61
+ system "chmod +x #{ pre_hook }"
62
+ system "scp #{ pre_hook } #{ remote.user }@#{ remote.hostname }:#{ remote.path }/.git/hooks/"
63
+ say '--> [ok]', :green
64
+ invoke 'add_post_receive_hook', remote
65
+ end
66
+
67
+ desc 'setup:clone_repository TARGET', 'sets up a remote for blazing deployments'
68
+ def add_post_receive_hook
69
+ say 'adding post-receive hook'
70
+ post_hook = "deploy/post-receive"
71
+ template('templates/post-hook.tt', post_hook)
72
+ system "chmod +x #{ post_hook }"
73
+ system "scp #{ post_hook } #{ remote.user }@#{ remote.hostname }:#{ remote.path }/.git/hooks/"
74
+ say '--> [ok]', :green
75
+ invoke 'add_remote', remote
76
+ end
77
+
78
+ desc 'setup:add_remote TARGET', 'adds a git remote for the given remote'
79
+ def add_remote
80
+ say 'adding remote as remote to repository'
81
+ system "git remote add #{ remote.name } #{ remote.user }@#{ remote.hostname }:#{ remote.path }"
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,3 @@
1
+ module Blazing
2
+ VERSION = "0.0.1"
3
+ end
@@ -1,5 +1,19 @@
1
+ require 'thor'
2
+ require 'thor/group'
3
+ require 'blazing'
4
+ require 'blazing/cli/base'
5
+
6
+ require 'blazing/config'
7
+ require 'blazing/logger'
8
+ require 'blazing/target'
9
+ require 'blazing/remote'
10
+ require 'blazing/recipe'
11
+ require 'blazing/object'
12
+ require 'blazing/cli/create'
13
+ require 'blazing/cli/hook'
14
+
1
15
  module Blazing
2
- 'blazing/base'
3
- 'blazing/cli'
4
- 'blazing/version'
16
+ DIRECTORY = 'config'
17
+ CONFIGURATION_FILE = 'config/blazing.rb'
18
+ LOGGER = Blazing::Logger.new
5
19
  end
@@ -0,0 +1,60 @@
1
+ module Blazing
2
+ module CLI
3
+ class Base < Thor
4
+
5
+ #
6
+ # Configure blazing in current working dir
7
+ #
8
+ desc 'init', 'prepare project for blazing deploys'
9
+ def init
10
+ target = ask "Deployment Target: (ie username@host:/path/to/app)"
11
+ origin = `git remote show origin|grep "Fetch URL"`.split[2]
12
+ if yes? "Get code from here: #{origin} ?"
13
+ repository = origin
14
+ else
15
+ repository = ask "Repository URL: (ie username@host:/path/to/app)"
16
+ end
17
+
18
+ Blazing::CLI::Create.new([repository, target]).invoke_all
19
+ end
20
+
21
+ #
22
+ # Setup target for deployment
23
+ #
24
+ desc 'setup TARGET_NAME', 'setup or update blazing on specified target and deploy'
25
+ def setup(target_name = nil)
26
+ config = Blazing::Config.load
27
+ target = config.find_target(target_name)
28
+ LOGGER.info "setting up target #{target.name}"
29
+ target.setup
30
+
31
+ # TODO: Abstract this into module and load it where we need it. Methods / actions should have
32
+ # a success and failure message
33
+ if $?.exitstatus == 0
34
+ LOGGER.success "successfully set up target #{target.name}"
35
+ else
36
+ LOGGER.error "failed setting up target #{target.name}"
37
+ end
38
+ end
39
+
40
+ #
41
+ # Deploy to target
42
+ #
43
+ desc 'deploy TARGET', 'deploy to TARGET'
44
+ def deploy(target_name = nil)
45
+ config = Blazing::Config.load
46
+ target = config.find_target(target_name)
47
+ LOGGER.info "deploying target #{target.name}"
48
+ target.deploy
49
+
50
+ if $?.exitstatus == 0
51
+ LOGGER.success "successfully deployed target #{target.name}"
52
+ else
53
+ LOGGER.error "failed deploying on target #{target.name}"
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
60
+ end