blazing 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ module Blazing
2
+ module CLI
3
+ class Create < Thor::Group
4
+
5
+ desc 'create a blazing config file'
6
+
7
+ include Thor::Actions
8
+
9
+ argument :repository
10
+ argument :remote
11
+
12
+ def self.source_root
13
+ File.dirname(__FILE__)
14
+ end
15
+
16
+ def create_blazing_dir
17
+ empty_directory Blazing::DIRECTORY
18
+ end
19
+
20
+ def create_config_file
21
+ template 'templates/blazing.tt', Blazing::CONFIGURATION_FILE
22
+ say "Blazing config file has been created in #{Blazing::CONFIGURATION_FILE} with a default remote."
23
+ say "Check the config and then setup your remote with blazing setup REMOTE"
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,20 @@
1
+ module Blazing
2
+ module CLI
3
+ class Hook < Thor
4
+
5
+ include Thor::Actions
6
+
7
+ def self.source_root
8
+ File.dirname(__FILE__)
9
+ end
10
+
11
+ argument :target
12
+
13
+ desc 'generate', 'generate post-receive hook from template'
14
+ def generate
15
+ template('templates/post-hook.tt', '/tmp/post-receive')
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ #
2
+ # blazing config file -- generated on <%= Time.now %>
3
+ #
4
+
5
+ repository '<%= repository %>'
6
+
7
+ target 'agoodname', :deploy_to => 'user@host:path/to/your/app'
8
+
9
+ use 'rvm', :ruby => 'set_your_ruby@and_your_gemset'
10
+ use 'bundler'
@@ -3,4 +3,4 @@
3
3
  require 'rubygems'
4
4
  require 'blazing'
5
5
 
6
- Blazing::Remote.pre_receive(<%= target.name %>)
6
+ Blazing::Remote.post_receive('<%= target %>')
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require 'blazing'
6
+ require 'blazing/cli'
7
+ require 'blazing/remote'
8
+
9
+ Blazing::Remote.pre_receive('<%= remote.name %>')
@@ -1,72 +1,85 @@
1
- require 'thor/group'
2
- require 'blazing/target'
1
+ module Blazing
2
+ class Config
3
+
4
+ class << self
5
+
6
+ #
7
+ # Read the Configuration File
8
+ #
9
+ def read(&block)
10
+ config = Blazing::Config.new
11
+ config.instance_eval(&block)
12
+ return config
13
+ end
14
+
15
+ #
16
+ # Load configuration file and parse it
17
+ #
18
+ def load
19
+ # TODO: shorten with something like this: new.instance_eval(File.read(guardfile_path), guardfile_path, 1)
20
+ config = read do
21
+ instance_eval(File.read(Blazing::CONFIGURATION_FILE))
22
+ end
23
+ end
24
+
25
+ #
26
+ # DSL Setter helper method
27
+ #
28
+ def dsl_setter(*names)
29
+ names.each do |name|
30
+ define_method name do |value = nil|
31
+ if value
32
+ instance_variable_set("@#{name}", value)
33
+ else
34
+ instance_variable_get("@#{name}")
35
+ end
36
+ end
37
+ end
38
+ end
3
39
 
4
- class Blazing::Config
5
-
6
- attr_accessor :targets, :file
7
-
8
- def initialize
9
- @targets = []
10
- @file = File.open('deploy/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
- return config
17
- end
18
-
19
- def target(name, &block)
20
- @targets << Blazing::Target.new(name, @repository, &block)
21
- end
22
-
23
- def repository(url)
24
- @repository = url
25
- end
26
-
27
- def determine_target
28
- target = case
29
- when self.targets.size == 1 && !self.targets.first.location.nil?
30
- self.targets.first
31
-
32
- when !self.default.default_target.nil?
33
- self.targets.find { |t| t.name == self.default.default_target }
40
+ end
34
41
 
35
- when self.default && !self.default.hostname.nil?
36
- self.default
37
- end
42
+ dsl_setter :repository
43
+ attr_accessor :targets, :recipes
38
44
 
39
- return target
40
- end
45
+ def initialize
46
+ @targets = []
47
+ @recipes = []
48
+ end
41
49
 
42
- def default
43
- self.targets.find { |t| t.name == :blazing}
44
- end
45
-
46
- # TODO: Why does thor break when this is put into an external file config folder?
47
- class Create < Thor::Group
50
+ def target(name, options = {}, &target_definition)
51
+ # TODO: implement if needed: target_definition.call if target_definition
52
+ @targets << Blazing::Target.new(name, options)
53
+ end
48
54
 
49
- desc 'creates a blazing config file'
55
+ def use(name, options = {}, &recipe_definition)
56
+ #TODO: implement if needed: recipe_definition.call if recipe_definition
57
+ @recipes << Blazing::Recipe.new(name, options)
58
+ end
50
59
 
51
- include Thor::Actions
60
+ #
61
+ # Determines which target is picked, based on defaults and CLI argument
62
+ # If only one target is defined, it is the default one
63
+ #
64
+ def find_target(target_name)
65
+ if target_name
66
+ target = targets.find {|target| target.name == target_name }
67
+ end
52
68
 
53
- argument :username
54
- argument :hostname
55
- argument :path
56
- argument :repository
69
+ if target.nil? && targets.size == 1
70
+ target = targets.first
71
+ end
57
72
 
58
- def self.source_root
59
- File.dirname(__FILE__)
60
- end
73
+ if target.nil?
74
+ target = targets.find {|target| target.default }
75
+ end
61
76
 
62
- def create_blazing_dir
63
- empty_directory 'deploy'
64
- end
77
+ if target.nil?
78
+ raise 'no target specified and no default targets found'
79
+ end
65
80
 
66
- def create_config_file
67
- template('templates/blazing.tt', "deploy/blazing.rb")
81
+ target
68
82
  end
69
83
 
70
84
  end
71
-
72
85
  end
@@ -0,0 +1,113 @@
1
+ module Blazing
2
+ class Logger
3
+
4
+ @@use_color = true
5
+ # TODO: implement non colored output, allow to pass option from commandline
6
+
7
+ [:info, :success, :warn, :error].each do |type|
8
+ define_method type do |message|
9
+ message(message, type)
10
+ end
11
+ end
12
+
13
+ def prefix
14
+ "[".red + "BLAZING".yellow + "] ".red + '*** '
15
+ end
16
+
17
+ def postfix
18
+ ' ***'
19
+ end
20
+
21
+ def message(message, type)
22
+ case type
23
+ when :info
24
+ puts prefix + message.blue + postfix
25
+ when :success
26
+ puts prefix + message.green + postfix
27
+ when :warn
28
+ puts prefix + message.yellow + postfix
29
+ when :error
30
+ puts prefix + message.red + postfix
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+
37
+ class String
38
+
39
+ # 00 Turn off all attributes
40
+ # 01 Set bright mode
41
+ # 04 Set underline mode
42
+ # 05 Set blink mode
43
+ # 07 Exchange foreground and background colors
44
+ # 08 Hide text (foreground color would be the same as background)
45
+ # 30 Black text
46
+ # 31 Red text
47
+ # 32 Green text
48
+ # 33 Yellow text
49
+ # 34 Blue text
50
+ # 35 Magenta text
51
+ # 36 Cyan text
52
+ # 37 White text
53
+ # 39 Default text color
54
+ # 40 Black background
55
+ # 41 Red background
56
+ # 42 Green background
57
+ # 43 Yellow background
58
+ # 44 Blue background
59
+ # 45 Magenta background
60
+ # 46 Cyan background
61
+ # 47 White background
62
+ # 49 Default background col
63
+
64
+ def black
65
+ string = "\033[30m"
66
+ string << self
67
+ string << "\033[0m"
68
+ end
69
+
70
+ def red
71
+ string = "\033[31m"
72
+ string << self
73
+ string << "\033[0m"
74
+ end
75
+
76
+ def green
77
+ string = "\033[32m"
78
+ string << self
79
+ string << "\033[0m"
80
+ end
81
+
82
+ def yellow
83
+ string = "\033[33m"
84
+ string << self
85
+ string << "\033[0m"
86
+ end
87
+
88
+ def blue
89
+ string = "\033[34m"
90
+ string << self
91
+ string << "\033[0m"
92
+ end
93
+
94
+ def purple
95
+ string = "\033[35m"
96
+ string << self
97
+ string << "\033[0m"
98
+ end
99
+
100
+ def cyan
101
+ string = "\033[36m"
102
+ string << self
103
+ string << "\033[0m"
104
+ end
105
+
106
+ def white
107
+ string = "\033[37m"
108
+ string << self
109
+ string << "\033[0m"
110
+ end
111
+
112
+ end
113
+
@@ -0,0 +1,8 @@
1
+ class Object
2
+
3
+ # Borrowed from rails
4
+ def blank?
5
+ respond_to?(:empty?) ? empty? : !self
6
+ end
7
+
8
+ end
@@ -0,0 +1,30 @@
1
+ module Blazing
2
+ class Recipe
3
+
4
+ attr_accessor :name, :options
5
+
6
+ def initialize(name, options = {})
7
+ @name = name.to_s
8
+ @options = options
9
+ end
10
+
11
+ end
12
+ end
13
+
14
+ # TODO: recipes as gems: blazing_hoptoad, blazing_rpm etc.
15
+ # TODO: provide setup, run and use methods and ability to override the whole recipe
16
+ # TODO: Must be callable from global namespace and from remote block
17
+
18
+ # TODO: make it easy to keep recipe externally and use git submodule
19
+ #
20
+ # TODO: later, make it possible to keep recipe and setup of all projects in
21
+ # a central repo:
22
+ #
23
+ # /recipes
24
+ # /projects/
25
+ # " " someproject.rb
26
+ # " " anotherpoject.rb
27
+ #
28
+ #
29
+ # ????
30
+
@@ -1,8 +1,43 @@
1
- #
2
- # Stuff that runs on remote machine
3
- #
4
- class Blazing::Remote < Thor
1
+ module Blazing
2
+ class Remote
5
3
 
6
-
4
+ # TODO: RVM
5
+ # TODO: Bundler
6
+ # TODO: Check if post-hook and blazing versions match
7
+
8
+ class << self
9
+
10
+ def post_receive(target)
11
+ set_git_dir
12
+ reset_head
13
+ end
14
+
15
+ def set_git_dir
16
+ if ENV['GIT_DIR'] == '.'
17
+ Dir.chdir('..')
18
+ ENV['GIT_DIR'] = '.git'
19
+ end
20
+ end
21
+
22
+ def reset_head
23
+ system 'git reset --hard HEAD'
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ # if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm')
32
+ # begin
33
+ # rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
34
+ # rvm_lib_path = File.join(rvm_path, 'lib')
35
+ # $LOAD_PATH.unshift rvm_lib_path
36
+ # require 'rvm'
37
+ # RVM.use_from_path! File.dirname(File.dirname(__FILE__))
38
+ # rescue LoadError
39
+ # # RVM is unavailable at this point.
40
+ # raise "RVM ruby lib is currently unavailable."
41
+ # end
42
+ # end
7
43
 
8
- end
@@ -1,87 +1,51 @@
1
- class Blazing::Target
1
+ module Blazing
2
+ class Target < Config
2
3
 
3
- attr_accessor :name, :user, :hostname, :path, :recipes, :target_name, :default_target, :repository
4
+ attr_accessor :name
4
5
 
5
- def initialize(name, repository, &block)
6
- @name = name
7
- @repository = repository
8
- instance_eval &block
9
- end
6
+ @@configuration_options = [:deploy_to, :host, :user, :path, :default]
10
7
 
11
- def deploy_to(location)
12
- @user = location.match('(.*)@')[1]
13
- @hostname = location.match('@(.*):')[1]
14
- @path = location.match(':(.*)')[1]
15
- end
8
+ def initialize(name, options = {})
9
+ @name = name.to_s
10
+ @@configuration_options.each do |option|
11
+ instance_variable_set("@#{option}", options[option])
12
+ self.class.send(:attr_accessor, option)
13
+ end
16
14
 
17
- def location
18
- # TODO: build this together more carefully, checking for emtpy hostname etc...
19
- @location ||= "#{ @user }@#{ @hostname }:#{ @path }"
20
- end
15
+ # If the :deploy_to option is given, user, host and path are overriden
16
+ unless deploy_to.blank?
17
+ @host = deploy_to.scan(/@(.*):/).join
18
+ @user = deploy_to.scan(/(.*)@/).join
19
+ @path = deploy_to.scan(/:(.*)/).join
20
+ end
21
21
 
22
- # Only used in global target for setting default target
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
22
+ # Raise an error if one of the required options is still empty
23
+ [:host, :user, :path].each do |option|
24
+ raise "#{option} can't be blank!" if instance_variable_get("@#{option}").blank?
25
+ end
26
+ end
29
27
 
30
- include Thor::Actions
28
+ def setup
31
29
 
32
- def self.source_root
33
- File.dirname(__FILE__)
34
- end
35
-
36
- argument :target
30
+ # TODO: Log some output?
31
+ # TODO: install post-receive hook and make it executable
37
32
 
38
- desc 'setup:setup_repository TARGET', 'sets up a target for blazing deployments'
39
- def setup_repository
33
+ config = Blazing::Config.load
34
+ clone_command = "if [ -e #{path} ]; then \
35
+ echo 'directory exists already'; else \
36
+ git clone #{config.repository} #{path} && cd #{path} && git config receive.denyCurrentBranch ignore; fi"
40
37
 
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 #{ target.repository } #{ target.path }; fi"
45
- system "ssh #{ target.user }@#{ target.hostname } '#{ command }'"
46
- if $? == 0
47
- say '--> [ok]', :green
48
- invoke 'add_pre_receive_hook', target
49
- else
50
- say '--> [FAILED]', :red
51
- say '[BLAZING] -- ROLLING BACK', :blue
52
- return
53
- end
54
- end
38
+ system "ssh #{user}@#{host} '#{clone_command}'"
39
+ system "git remote add #{name} #{user}@#{host}:#{path}"
55
40
 
56
- desc 'setup:clone_repository TARGET', 'sets up a target for blazing deployments'
57
-
58
- def add_pre_receive_hook
59
- say 'adding pre-receive hook'
60
- pre_hook = "deploy/pre-receive"
61
- template('templates/pre-hook.tt', pre_hook)
62
- system "chmod +x #{ pre_hook }"
63
- system "scp #{ pre_hook } #{ target.user }@#{ target.hostname }:#{ target.path }/.git/hooks/"
64
- say '--> [ok]', :green
65
- invoke 'add_post_receive_hook', target
41
+ Blazing::CLI::Hook.new([name]).generate #.generate(target.name)
42
+ system "scp /tmp/post-receive #{user}@#{host}:#{path}/.git/hooks/post-receive"
43
+ system "ssh #{user}@#{host} 'chmod +x #{path}/.git/hooks/post-receive'"
66
44
  end
67
45
 
68
- desc 'setup:clone_repository TARGET', 'sets up a target for blazing deployments'
69
- def add_post_receive_hook
70
- say 'adding post-receive hook'
71
- post_hook = "deploy/post-receive"
72
- template('templates/post-hook.tt', post_hook)
73
- system "chmod +x #{ post_hook }"
74
- system "scp #{ post_hook } #{ target.user }@#{ target.hostname }:#{ target.path }/.git/hooks/"
75
- say '--> [ok]', :green
76
- invoke 'add_remote', target
77
- end
78
-
79
- desc 'setup:add_remote TARGET', 'adds a git remote for the given target'
80
- def add_remote
81
- say 'adding target as remote to repository'
82
- system "git remote add #{ target.name } #{ target.user }@#{ target.hostname }:#{ target.path }"
46
+ def deploy
47
+ system "git push #{name}"
83
48
  end
84
49
 
85
50
  end
86
-
87
51
  end