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.
@@ -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