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