stack 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/Rakefile +13 -1
- data/VERSION.yml +4 -0
- data/bin/stack +3 -2
- data/lib/core_ext/hash.rb +63 -0
- data/lib/stack/configuration.rb +16 -0
- data/lib/stack/generator.rb +16 -0
- data/lib/stack/runner.rb +42 -0
- data/lib/stack.rb +61 -7
- metadata +7 -4
- data/.document +0 -5
- data/.gitignore +0 -21
- data/VERSION +0 -1
data/Rakefile
CHANGED
@@ -10,7 +10,9 @@ begin
|
|
10
10
|
gem.email = "dev@sixones.com"
|
11
11
|
gem.homepage = "http://github.com/sixones/stack"
|
12
12
|
gem.authors = ["sixones"]
|
13
|
+
gem.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
|
13
14
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
15
|
+
|
14
16
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
17
|
end
|
16
18
|
rescue LoadError
|
@@ -43,10 +45,20 @@ task :default => :test
|
|
43
45
|
|
44
46
|
require 'rake/rdoctask'
|
45
47
|
Rake::RDocTask.new do |rdoc|
|
46
|
-
|
48
|
+
if File.exist?('VERSION.yml')
|
49
|
+
config = YAML.load(File.read('VERSION.yml'))
|
50
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
51
|
+
else
|
52
|
+
version = ""
|
53
|
+
end
|
47
54
|
|
48
55
|
rdoc.rdoc_dir = 'rdoc'
|
49
56
|
rdoc.title = "stack #{version}"
|
50
57
|
rdoc.rdoc_files.include('README*')
|
51
58
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
59
|
end
|
60
|
+
|
61
|
+
desc "provide a console like merb -i or script/console"
|
62
|
+
task :console do
|
63
|
+
exec "irb -r irb/completion -r lib/stack.rb"
|
64
|
+
end
|
data/VERSION.yml
ADDED
data/bin/stack
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
class Hash
|
2
|
+
|
3
|
+
# Returns a new hash just like this one, but with all the string keys expressed as symbols.
|
4
|
+
# Also applies to hashes within self.
|
5
|
+
# Based on an implementation within Rails 2.x, thanks Rails!
|
6
|
+
def deep_symbolize
|
7
|
+
target = dup
|
8
|
+
target.inject({}) do |memo, (key, value)|
|
9
|
+
value = value.deep_symbolize if value.is_a?(Hash)
|
10
|
+
memo[(key.to_sym rescue key) || key] = value
|
11
|
+
memo
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Subtracts one hash from another by removing keys from the actor and recursing on any hash values.
|
16
|
+
# Returns a new Hash without affecting the actors.
|
17
|
+
# Example 1:
|
18
|
+
# {:foo=>"bar"} - {:foo=>"bar"} == {}
|
19
|
+
# Example 2 of deep nesting:
|
20
|
+
# {:foo=>{:bar=>"baz", :car=>"naz"}, :bar=>"baz"} - {:foo=>{:car=>"naz"}} == {:foo=>{:bar=>"baz"}, :bar=>"baz"}
|
21
|
+
def -(arg)
|
22
|
+
target = dup; actor = arg.dup
|
23
|
+
actor.each do |key, value|
|
24
|
+
if value.is_a?(Hash)
|
25
|
+
target[key] = target[key] - value
|
26
|
+
else
|
27
|
+
target.delete(key)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
return target
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a new hash just like this one, but with all STRING keys and values evaluated
|
34
|
+
# and rendered as liquid templates using the provided payload hash.
|
35
|
+
def deep_liquify(payload={})
|
36
|
+
target = dup
|
37
|
+
target.inject({}) do |memo, (key, value)|
|
38
|
+
value = value.deep_liquify(payload) if value.is_a?(Hash)
|
39
|
+
value = value.liquify(payload) if value.is_a?(String)
|
40
|
+
key = key.liquify(payload) if key.is_a?(String)
|
41
|
+
memo[(key.to_sym rescue key) || key] = value
|
42
|
+
memo
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Merges self with another hash, recursively.
|
47
|
+
#
|
48
|
+
# This code was lovingly stolen from some random gem:
|
49
|
+
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
50
|
+
#
|
51
|
+
# Thanks to whoever made it.
|
52
|
+
def deep_merge(hash)
|
53
|
+
target = dup
|
54
|
+
hash.keys.each do |key|
|
55
|
+
if hash[key].is_a? Hash and self[key].is_a? Hash
|
56
|
+
target[key] = target[key].deep_merge(hash[key])
|
57
|
+
next
|
58
|
+
end
|
59
|
+
target[key] = hash[key]
|
60
|
+
end
|
61
|
+
target
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Stack
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :source, :target
|
4
|
+
|
5
|
+
def initialize(hash = nil)
|
6
|
+
self.from_hash(hash)
|
7
|
+
end
|
8
|
+
|
9
|
+
def from_hash(hash)
|
10
|
+
if (hash != nil)
|
11
|
+
@source = hash[:source]
|
12
|
+
@target = hash[:target]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/stack/runner.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
module Stack
|
2
|
+
class Runner
|
3
|
+
attr_accessor :configuration
|
4
|
+
attr_accessor :command
|
5
|
+
attr_accessor :arguments
|
6
|
+
|
7
|
+
def initialize(argv)
|
8
|
+
@argv = argv
|
9
|
+
@options = { }
|
10
|
+
|
11
|
+
parse!
|
12
|
+
end
|
13
|
+
|
14
|
+
# Parse options, command and arguments
|
15
|
+
def parse!
|
16
|
+
options = Stack::parse! @argv
|
17
|
+
|
18
|
+
@configuration = Stack::Configuration.new(options)
|
19
|
+
|
20
|
+
@command = @argv.shift
|
21
|
+
@arguments = @argv
|
22
|
+
end
|
23
|
+
|
24
|
+
# Run stack!
|
25
|
+
def run!
|
26
|
+
if @command.nil?
|
27
|
+
@command = "generate"
|
28
|
+
end
|
29
|
+
|
30
|
+
if Stack::COMMANDS.include?(@command)
|
31
|
+
run_command
|
32
|
+
else
|
33
|
+
abort "Unknown command: #{@command}. Use one of #{Stack::COMMANDS.join(", ")}."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Runs the specified command
|
38
|
+
def run_command
|
39
|
+
Stack::Generator.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/stack.rb
CHANGED
@@ -1,28 +1,82 @@
|
|
1
1
|
# rubygems
|
2
2
|
require 'rubygems'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
require 'core_ext/hash'
|
6
|
+
|
7
|
+
require 'stack/configuration'
|
8
|
+
require 'stack/generator'
|
9
|
+
require 'stack/runner'
|
3
10
|
|
4
11
|
module Stack
|
5
|
-
# Default options used by stack, overridden from the command line or
|
12
|
+
# Default options used by stack, overridden from the command line or YML configration file.
|
6
13
|
DEFAULTS = {
|
7
|
-
|
14
|
+
:source => '.',
|
15
|
+
:target => File.join('.', '_stack')
|
8
16
|
}.freeze
|
9
17
|
|
18
|
+
# Array of valid commands stack can use
|
19
|
+
COMMANDS = %w(create generate server)
|
20
|
+
|
21
|
+
class << self
|
22
|
+
attr_accessor :runner
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parses the options configuration from the command line
|
26
|
+
def self.parse!(argv)
|
27
|
+
config = { }
|
28
|
+
|
29
|
+
parser = OptionParser.new do |opts|
|
30
|
+
opts.banner = "Usage: stack [options] #{Stack::COMMANDS.join('|')}"
|
31
|
+
|
32
|
+
opts.on("-s", "--source [DIR]", "Directory to use as the source for generating a stack") do |l| config[:source] = l unless l.nil? end
|
33
|
+
opts.on("-t", "--target [DIR]", "Directory to use as the target directory") do |l| config[:target] = l unless l.nil? end
|
34
|
+
|
35
|
+
opts.on_tail("-h", "--help", "Show this message") { puts opts; exit }
|
36
|
+
opts.on_tail("-v", "--version" "Show version") do puts "stack #{Stack::version}"; exit; end
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.parse! argv
|
40
|
+
|
41
|
+
options = Stack::configuration(config)
|
42
|
+
|
43
|
+
options
|
44
|
+
end
|
45
|
+
|
46
|
+
# Merges the configuration from YAML file, command line and defaults
|
10
47
|
def self.configuration(override)
|
11
48
|
config = { }
|
49
|
+
source = File.join(override['source'] || Stack::DEFAULTS[:source])
|
50
|
+
|
51
|
+
config_file = File.join(source, "_stack.yml")
|
12
52
|
|
13
53
|
begin
|
14
|
-
|
15
|
-
rescue => error
|
54
|
+
yml = YAML.load_file(config_file)
|
16
55
|
|
56
|
+
raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
|
57
|
+
|
58
|
+
yml.each { |key, value| config[key.to_sym] = value }
|
59
|
+
|
60
|
+
STDOUT.puts "Configuration loaded from #{config_file}"
|
61
|
+
rescue => error
|
62
|
+
STDERR.puts "WARNING: Could not read configuration. Using defaults (and options)."
|
63
|
+
STDERR.puts "\t" + error.to_s
|
17
64
|
end
|
18
65
|
|
19
66
|
# Merge configuration with defaults
|
20
|
-
Stack::DEFAULTS.deep_merge(
|
67
|
+
Stack::DEFAULTS.deep_merge(override).deep_merge(config)
|
21
68
|
end
|
22
69
|
|
23
70
|
# Stacks current version
|
24
71
|
def self.version
|
25
|
-
|
26
|
-
|
72
|
+
version_file = File.join(File.dirname(__FILE__), *%w[.. VERSION.yml])
|
73
|
+
|
74
|
+
if File.exist?(version_file)
|
75
|
+
yml = YAML.load(File.read(version_file))
|
76
|
+
|
77
|
+
"#{yml[:major]}.#{yml[:minor]}.#{yml[:patch]}"
|
78
|
+
else
|
79
|
+
"0.0.0"
|
80
|
+
end
|
27
81
|
end
|
28
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sixones
|
@@ -32,13 +32,16 @@ extra_rdoc_files:
|
|
32
32
|
- LICENSE
|
33
33
|
- README.rdoc
|
34
34
|
files:
|
35
|
-
- .document
|
36
|
-
- .gitignore
|
37
35
|
- LICENSE
|
38
36
|
- README.rdoc
|
39
37
|
- Rakefile
|
40
|
-
- VERSION
|
38
|
+
- VERSION.yml
|
39
|
+
- bin/stack
|
40
|
+
- lib/core_ext/hash.rb
|
41
41
|
- lib/stack.rb
|
42
|
+
- lib/stack/configuration.rb
|
43
|
+
- lib/stack/generator.rb
|
44
|
+
- lib/stack/runner.rb
|
42
45
|
- test/helper.rb
|
43
46
|
- test/test_stack.rb
|
44
47
|
has_rdoc: true
|
data/.document
DELETED
data/.gitignore
DELETED
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.0.1
|