wizard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
22
+ *.rdb
@@ -0,0 +1,5 @@
1
+ # v0.0.1 (Prof of concept)
2
+
3
+ * Common heleprs
4
+ * Generator (supporting actions: touch, mkfile, mkdir, compile, cp, append,
5
+ prepend, inject)
File without changes
@@ -0,0 +1,44 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "wizard"
8
+ gem.summary = %Q{Projects generator and recipes compiler.}
9
+ gem.description = <<-DESCR
10
+ Projects generator...
11
+ DESCR
12
+ gem.email = "chris@nu7hat.ch"
13
+ gem.homepage = "http://github.com/nu7hatch/wizard"
14
+ gem.authors = ["Kriss 'nu7hatch' Kowalik"]
15
+ gem.add_development_dependency "rspec", "~> 2.0"
16
+ gem.add_development_dependency "mocha", "~> 0.9"
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rspec/core/rake_task'
24
+ RSpec::Core::RakeTask.new(:spec) do |t|
25
+ t.pattern = 'spec/**/*_spec.rb'
26
+ t.rspec_opts = %q[--colour --backtrace]
27
+ end
28
+
29
+ RSpec::Core::RakeTask.new(:rcov) do |t|
30
+ t.rcov = true
31
+ t.rspec_opts = %q[--colour --backtrace]
32
+ t.rcov_opts = %q[--exclude "spec" --text-report]
33
+ end
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+ rdoc.rdoc_dir = 'rdoc'
41
+ rdoc.title = "Wizard #{version}"
42
+ rdoc.rdoc_files.include('README*')
43
+ rdoc.rdoc_files.include('lib/**/*.rb')
44
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,12 @@
1
+ require 'fileutils'
2
+
3
+ module Wizard
4
+
5
+ require 'wizard/helpers'
6
+
7
+ extend Helpers
8
+
9
+ require 'wizard/formula'
10
+ require 'wizard/spells'
11
+
12
+ end # Wizard
@@ -0,0 +1,23 @@
1
+ module Wizard
2
+ class Formula
3
+
4
+ include Helpers
5
+
6
+ COLORIZERS = {
7
+ :success => :green,
8
+ :error => :red,
9
+ }
10
+
11
+ def self.colorizers
12
+ COLORIZERS
13
+ end
14
+
15
+ def render(spell)
16
+ line = " "
17
+ line += a(spell.to_s, console_width-spell.status.to_s.size-3) + " "
18
+ line += c(spell.status.to_s, self.class.colorizers[spell.status], true)
19
+ say! line
20
+ end
21
+
22
+ end # Formula
23
+ end # Ryori
@@ -0,0 +1,63 @@
1
+ module Wizard
2
+ module Helpers
3
+
4
+ COLORS = {
5
+ :black => 30,
6
+ :red => 31,
7
+ :green => 32,
8
+ :yellow => 33,
9
+ :blue => 34,
10
+ :purple => 35,
11
+ :cyan => 36,
12
+ :white => 37,
13
+ }
14
+
15
+ # Display colorized output (no new line at the end).
16
+ def say(text, color=nil, bold=false)
17
+ print(color ? colorize(text, color, bold) : text)
18
+ end
19
+
20
+ # Writes given text to <tt>$stdout</tt>.
21
+ def print(*args)
22
+ res = $stdout.write(*args)
23
+ $stdout.flush
24
+ return res
25
+ end
26
+
27
+ # Display colorized output.
28
+ def say!(text, color=nil, bold=false)
29
+ say(text+"\n", color, bold)
30
+ end
31
+
32
+ # Colorize specified text with given color.
33
+ def colorize(text, color=:white, bold=false)
34
+ color = COLORS[color] || COLORS[:white]
35
+ return "\e[#{bold ? 1 : 0};#{color}m#{text}\e[0m"
36
+ end
37
+ alias :c :colorize
38
+
39
+ # Display given text adjusted to the desired length.
40
+ #
41
+ # adjust("This", 30, "-")
42
+ # adjust("is", 30, "-")
43
+ # adjust("SPARTA!", 30, "-")
44
+ #
45
+ # will produce:
46
+ #
47
+ # This -------------------------
48
+ # is ---------------------------
49
+ # SPARTA! ----------------------
50
+ def adjust(text, size=nil, delim=".")
51
+ size ||= console_width
52
+ delims = size-text.size
53
+ delims > 0 ? text+" "+(c(delim*(delims-1), :black)) : text
54
+ end
55
+ alias :a :adjust
56
+
57
+ # Returns actual width of console line.
58
+ def console_width
59
+ `stty size`.split.last.to_i
60
+ end
61
+
62
+ end # Helpers
63
+ end # Wizard
@@ -0,0 +1,12 @@
1
+ module Wizard
2
+ module Spells
3
+
4
+ require "wizard/spells/base"
5
+ require "wizard/spells/make_dir"
6
+ require "wizard/spells/make_file"
7
+ require "wizard/spells/update_file"
8
+ require "wizard/spells/compile_template"
9
+ require "wizard/spells/execute_shell"
10
+
11
+ end # Spells
12
+ end # Wizard
@@ -0,0 +1,84 @@
1
+ module Wizard
2
+ module Spells
3
+ class Base
4
+
5
+ include Helpers
6
+
7
+ class << self
8
+ # Should all actions be performed in force mode?
9
+ def all_forced?
10
+ defined?(@@force_all) and !!@@force_all
11
+ end
12
+
13
+ # Set force mode for all apps.
14
+ # XXX. deadlocks can raise here.
15
+ def force_all!
16
+ @@force_all = true
17
+ end
18
+
19
+ # Creates shortcuts for given statuses:
20
+ #
21
+ # attr_status :my_status
22
+ #
23
+ # will produce methods:
24
+ #
25
+ # my_status! # => status!(:my_status)
26
+ # my_status? # => status?(:my_status)
27
+ #
28
+ def attr_status(*statuses)
29
+ statuses.each do |status|
30
+ define_method("#{status}!".to_sym) { status!(status.to_sym) }
31
+ define_method("#{status}?".to_sym) { status?(status.to_sym) }
32
+ protected "#{status}!".to_sym
33
+ end
34
+ end
35
+ end
36
+
37
+ # Shortcuts for the most commonly used statuses. We are creating
38
+ # <tt>success</tt> and <tt>error</tt> shortcuts by default.
39
+ attr_status :success, :error
40
+
41
+ # Returns status of currently performed operation.
42
+ def status
43
+ @status
44
+ end
45
+
46
+ # Returns +true+ when actual status equals the given one.
47
+ #
48
+ # status!(:success)
49
+ # status?(:success) # => true
50
+ # status?(:error) # => false
51
+ #
52
+ def status?(status)
53
+ self.status == status.to_sym
54
+ end
55
+
56
+ # Should be forced performing of current action?
57
+ def forced?
58
+ @force || self.class.all_forced?
59
+ end
60
+
61
+ # See Ryori::Makers::Base.force_all! for details.
62
+ def force_all!
63
+ self.class.force_all!
64
+ end
65
+
66
+ # Set force mode for current action.
67
+ def force!
68
+ @force = true
69
+ end
70
+
71
+ protected
72
+
73
+ # Set given status for actual operation.
74
+ #
75
+ # status!(:success)
76
+ # status!(:error)
77
+ #
78
+ def status!(status)
79
+ @status = status.to_sym
80
+ end
81
+
82
+ end # Base
83
+ end # Spells
84
+ end # Wizard
@@ -0,0 +1,27 @@
1
+ require 'wizard/spells/make_file'
2
+ require 'erb'
3
+
4
+ module Wizard
5
+ module Spells
6
+ class CompileTemplate < MakeFile
7
+
8
+ attr_reader :template
9
+
10
+ def initialize(filename, template, options={})
11
+ super(filename, nil, options)
12
+ @template = template
13
+ end
14
+
15
+ def perform_with_template_compilation
16
+ @content = ERB.new(File.read(template)).result(binding)
17
+ perform_without_template_compilation
18
+ rescue Object
19
+ error!
20
+ end
21
+
22
+ alias_method :perform_without_template_compilation, :perform
23
+ alias_method :perform, :perform_with_template_compilation
24
+
25
+ end # CompileTemplate
26
+ end # Spells
27
+ end # Wizard
@@ -0,0 +1,22 @@
1
+ module Wizard
2
+ module Spells
3
+ class ExecuteShell < Base
4
+
5
+ attr_reader :command, :output
6
+ attr_status :executed, :failed
7
+
8
+ def initialize(command, options={})
9
+ @command = command
10
+ @output = nil
11
+ end
12
+
13
+ def perform
14
+ return executed! if @output = `#{command} 2>&1` and $?.exitstatus == 0
15
+ failed!
16
+ rescue Object
17
+ error!
18
+ end
19
+
20
+ end # CompileTemplate
21
+ end # Spells
22
+ end # Wizard
@@ -0,0 +1,47 @@
1
+ module Wizard
2
+ class Formula
3
+
4
+ colorizers.merge!(
5
+ :created => :green,
6
+ :exist => :cyan,
7
+ :noaccess => :red,
8
+ )
9
+
10
+ def make_dir(dirname, options={})
11
+ spell = Spells::MakeDir.new(dirname, options)
12
+ spell.perform
13
+ render(spell)
14
+ end
15
+ alias_method :dir, :make_dir
16
+ alias_method :directory, :make_dir
17
+ alias_method :mkdir, :make_dir
18
+ alias_method :create_dir, :make_dir
19
+
20
+ end # Formula
21
+
22
+ module Spells
23
+ class MakeDir < Base
24
+
25
+ attr_reader :dirname, :chmod
26
+ attr_status :created, :exist, :noaccess
27
+
28
+ def initialize(dirname, options={})
29
+ @dirname = dirname
30
+ @chmod = options[:mode]
31
+ end
32
+
33
+ def perform
34
+ return exist! if File.exist?(dirname)
35
+ return created! if FileUtils.mkdir_p(dirname, :mode => chmod) == dirname
36
+ error!
37
+ rescue Errno::EACCES
38
+ noaccess!
39
+ rescue Object
40
+ error!
41
+ end
42
+
43
+ alias_method :to_s, :dirname
44
+
45
+ end # MakeDir
46
+ end # Spells
47
+ end # Wizard
@@ -0,0 +1,69 @@
1
+ module Wizard
2
+ class Formula
3
+
4
+ colorizers.merge!(
5
+ :created => :green,
6
+ :noaccess => :red,
7
+ :identical => :cyan,
8
+ :conflict => :yellow,
9
+ :updated => :green,
10
+ :skipped => :yellow
11
+ )
12
+
13
+ def make_file(filename, content=nil, options={})
14
+ spell = Spells::MakeFile.new(filename, content, options)
15
+ spell.perform
16
+ render(spell)
17
+ end
18
+ alias_method :file, :make_file
19
+ alias_method :mkfile, :make_file
20
+ alias_method :create_file, :make_file
21
+
22
+ end # Formula
23
+
24
+ module Spells
25
+ class MakeFile < Base
26
+
27
+ attr_reader :filename, :chmod, :content
28
+ attr_status :created, :noaccess, :identical, :conflict, :updated, :skipped
29
+
30
+ def initialize(filename, content=nil, options={})
31
+ @filename = filename
32
+ @content = content
33
+ @chmod = options[:mode]
34
+
35
+ force! if options[:force]
36
+ end
37
+
38
+ def perform
39
+ if File.exist?(filename)
40
+ return identical! if identical_content?
41
+ return status if conflict! and !forced?
42
+ end
43
+ return conflict? ? updated! : created! if create_file!
44
+ error!
45
+ rescue Errno::EACCES
46
+ noaccess!
47
+ rescue Object
48
+ error!
49
+ end
50
+
51
+ # Create current performed file, write its content and set proper chmod.
52
+ def create_file!
53
+ if File.open(filename, "w+") {|f| f.write(content) if content }
54
+ FileUtils.chmod(chmod, filename) if chmod
55
+ return true
56
+ end
57
+ end
58
+
59
+ # Returns +true+ when current file already exists and have the same
60
+ # content as given in initializer.
61
+ def identical_content?
62
+ File.read(filename) == content
63
+ end
64
+
65
+ alias_method :to_s, :filename
66
+
67
+ end # MakeFile
68
+ end # Spells
69
+ end # Wizard