dressmaker 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.
- data/README.rdoc +33 -0
- data/Rakefile +48 -0
- data/Rakefile2 +53 -0
- data/VERSION +1 -0
- data/bin/dressmaker +0 -0
- data/lib/dressmaker.rb +54 -0
- data/lib/dressmaker/configuration.rb +43 -0
- data/lib/dressmaker/configuration/directory_rule.rb +34 -0
- data/spec/fixtures/template-test/Pattern +6 -0
- data/spec/fixtures/template-test/bin/runner +0 -0
- data/spec/fixtures/template-test/bin/script +0 -0
- data/spec/generate_spec.rb +22 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +4 -0
- metadata +68 -0
data/README.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
= Dressmaker
|
2
|
+
|
3
|
+
== Beautiful templating
|
4
|
+
|
5
|
+
I wanted to do really simple application templating, and found Rubigen and Thor were both tied to a command-line interface paradigm, whereas I really just wanted to execute this stuff programmatically. I also wanted application templates to be entirely self-contained.
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
Inside your application
|
10
|
+
|
11
|
+
require 'dressmaker'
|
12
|
+
|
13
|
+
maker = Dressmaker.new('my-template', 'my-source')
|
14
|
+
maker.generate
|
15
|
+
|
16
|
+
And you're done! If you need to pass in options at generate time, simply pass generate some options.
|
17
|
+
|
18
|
+
maker.generate(:database => 'mysql')
|
19
|
+
|
20
|
+
Inside the template directory is a file, called Pattern. Here is a typical Pattern:
|
21
|
+
|
22
|
+
desc "make executable"
|
23
|
+
directory '/bin' do |dir|
|
24
|
+
dir.for('*') { |f|
|
25
|
+
File.chmod(0755, f)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
This would make everything inside bin executable.
|
30
|
+
|
31
|
+
== Caution!
|
32
|
+
|
33
|
+
Everything here is subject to change. This is just an egg of an idea.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
|
4
|
+
Jeweler::Tasks.new do |s|
|
5
|
+
s.name = "dressmaker"
|
6
|
+
s.description = s.summary = "Application templating in ruby. Define beautiful patterns and cut them out."
|
7
|
+
s.email = "joshbuddy@gmail.com"
|
8
|
+
s.homepage = "http://github.com/joshbuddy/dressmaker"
|
9
|
+
s.authors = ["Joshua Hull"]
|
10
|
+
s.files = FileList["[A-Z]*", "{lib,spec}/**/*"]
|
11
|
+
s.rubyforge_project = 'dressmaker'
|
12
|
+
end
|
13
|
+
Jeweler::GemcutterTasks.new
|
14
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
15
|
+
rubyforge.doc_task = "rdoc"
|
16
|
+
rubyforge.remote_doc_path = ''
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec'
|
23
|
+
require 'spec/rake/spectask'
|
24
|
+
task :spec => 'spec:all'
|
25
|
+
namespace(:spec) do
|
26
|
+
Spec::Rake::SpecTask.new(:all) do |t|
|
27
|
+
t.spec_opts ||= []
|
28
|
+
t.spec_opts << "-rubygems"
|
29
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
30
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Run all examples with RCov"
|
36
|
+
Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
|
37
|
+
t.spec_files = FileList['spec/**/*.rb']
|
38
|
+
t.rcov = true
|
39
|
+
t.rcov_opts = ['--exclude', 'spec']
|
40
|
+
end
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
desc "Generate documentation"
|
44
|
+
Rake::RDocTask.new do |rd|
|
45
|
+
rd.main = "README.rdoc"
|
46
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
47
|
+
rd.rdoc_dir = 'rdoc'
|
48
|
+
end
|
data/Rakefile2
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
libdir = File.expand_path("lib")
|
2
|
+
$:.unshift(libdir) unless $:.include?(libdir)
|
3
|
+
|
4
|
+
require 'usher'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |s|
|
9
|
+
s.name = "usher"
|
10
|
+
s.description = s.summary = "A general purpose routing library"
|
11
|
+
s.email = "joshbuddy@gmail.com"
|
12
|
+
s.homepage = "http://github.com/joshbuddy/usher"
|
13
|
+
s.authors = ["Joshua Hull"]
|
14
|
+
s.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"]
|
15
|
+
s.add_dependency 'fuzzyhash', '>=0.0.9'
|
16
|
+
s.rubyforge_project = 'joshbuddy-usher'
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
20
|
+
rubyforge.doc_task = "rdoc"
|
21
|
+
rubyforge.remote_doc_path = ''
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'spec'
|
28
|
+
require 'spec/rake/spectask'
|
29
|
+
task :spec => 'spec:all'
|
30
|
+
namespace(:spec) do
|
31
|
+
Spec::Rake::SpecTask.new(:all) do |t|
|
32
|
+
t.spec_opts ||= []
|
33
|
+
t.spec_opts << "-rubygems"
|
34
|
+
t.spec_opts << "--options" << "spec/spec.opts"
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "Run all examples with RCov"
|
41
|
+
Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
|
42
|
+
t.spec_files = FileList['spec/**/*.rb']
|
43
|
+
t.rcov = true
|
44
|
+
t.rcov_opts = ['--exclude', 'spec']
|
45
|
+
end
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
desc "Generate documentation"
|
49
|
+
Rake::RDocTask.new do |rd|
|
50
|
+
rd.main = "README.rdoc"
|
51
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
52
|
+
rd.rdoc_dir = 'rdoc'
|
53
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/dressmaker
ADDED
File without changes
|
data/lib/dressmaker.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
class Dressmaker
|
4
|
+
|
5
|
+
autoload :Configuration, File.join(File.dirname(__FILE__), 'dressmaker', 'configuration')
|
6
|
+
|
7
|
+
attr_reader :source, :destination
|
8
|
+
|
9
|
+
@@description_writer = $stdout
|
10
|
+
|
11
|
+
def self.description_writer
|
12
|
+
@@description_writer
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.inform(source, status)
|
16
|
+
description_writer << "%40s : %s" % [source.name, status] << "\n"
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(source, destination)
|
20
|
+
@source, @destination = source, destination
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
"Application generator"
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate(options = nil)
|
28
|
+
create_destination
|
29
|
+
copy_files_from_source
|
30
|
+
run_configuration(options)
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def create_destination
|
35
|
+
Dressmaker.inform(self, "creating destination")
|
36
|
+
FileUtils.mkdir_p(destination)
|
37
|
+
end
|
38
|
+
|
39
|
+
def copy_files_from_source
|
40
|
+
Dressmaker.inform(self, "copying files")
|
41
|
+
FileUtils.cp_r(entries_from_source, destination)
|
42
|
+
File.unlink(File.join(destination, 'Pattern'))
|
43
|
+
end
|
44
|
+
|
45
|
+
def entries_from_source
|
46
|
+
(Dir.entries(source) - ['.', '..']).map{|e| File.join(source, e)}
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_configuration(options)
|
50
|
+
configuration = Configuration.load(File.join(source, 'Pattern'), options)
|
51
|
+
configuration.process!(destination)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Dressmaker
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
autoload :DirectoryRule, File.join(File.dirname(__FILE__), 'configuration', 'directory_rule')
|
5
|
+
|
6
|
+
attr_accessor :description_holder
|
7
|
+
attr_reader :options
|
8
|
+
|
9
|
+
def self.load(file, options)
|
10
|
+
configuration = new(options)
|
11
|
+
configuration.instance_eval(File.read(file))
|
12
|
+
configuration
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@options = options
|
17
|
+
@rules = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def directory(directory, &block)
|
21
|
+
rule = DirectoryRule.new(directory, &block)
|
22
|
+
if rule.respond_to?(:description=)
|
23
|
+
rule.description = description_holder
|
24
|
+
self.description_holder = nil
|
25
|
+
end
|
26
|
+
@rules << rule
|
27
|
+
end
|
28
|
+
|
29
|
+
def process!(target)
|
30
|
+
@rules.each do |rule|
|
31
|
+
if rule.matches?(target)
|
32
|
+
rule.execute!(target)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :desc, :description_holder=
|
38
|
+
def desc(description)
|
39
|
+
@description_holder = description
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'ftools'
|
2
|
+
require "delegate"
|
3
|
+
|
4
|
+
class Dressmaker
|
5
|
+
class Configuration
|
6
|
+
class DirectoryRule
|
7
|
+
|
8
|
+
attr_reader :directory, :action
|
9
|
+
attr_accessor :description, :name
|
10
|
+
|
11
|
+
def initialize(directory, &action)
|
12
|
+
@directory = directory
|
13
|
+
@action = action
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(target)
|
17
|
+
self.name = "Directory (#{File.join(target, directory)})"
|
18
|
+
File.directory?(File.join(target, directory))
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute!(target)
|
22
|
+
Dressmaker.inform(self, description) if description
|
23
|
+
dir = DirectoryDelegator.new(File.open(File.join(target, directory)))
|
24
|
+
action.call(dir)
|
25
|
+
end
|
26
|
+
|
27
|
+
class DirectoryDelegator < SimpleDelegator
|
28
|
+
def for(pattern)
|
29
|
+
Dir["#{__getobj__.path}/#{pattern}"].each {|e| yield e}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
|
2
|
+
|
3
|
+
describe 'Dressmaker' do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
FileUtils.rm_rf(File.expand_path(File.join(File.dirname(__FILE__), 'output')))
|
7
|
+
FileUtils.mkdir_p(File.expand_path(File.join(File.dirname(__FILE__), 'output')))
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:each) do
|
11
|
+
FileUtils.rm_rf(File.expand_path(File.join(File.dirname(__FILE__), 'output')))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should generate" do
|
15
|
+
maker = Dressmaker.new(File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'template-test')), File.expand_path(File.join(File.dirname(__FILE__), 'output', 'template-test')))
|
16
|
+
maker.generate
|
17
|
+
File.exist?(File.expand_path(File.join(File.dirname(__FILE__), 'output', 'template-test', 'bin', 'runner'))).should be_true
|
18
|
+
File.executable?(File.expand_path(File.join(File.dirname(__FILE__), 'output', 'template-test', 'bin', 'runner'))).should be_true
|
19
|
+
File.executable?(File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'template-test', 'bin', 'runner'))).should be_false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dressmaker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Hull
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-11-06 00:00:00 -05:00
|
13
|
+
default_executable: dressmaker
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Application templating in ruby. Define beautiful patterns and cut them out.
|
17
|
+
email: joshbuddy@gmail.com
|
18
|
+
executables:
|
19
|
+
- dressmaker
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- README.rdoc
|
26
|
+
- Rakefile
|
27
|
+
- Rakefile2
|
28
|
+
- VERSION
|
29
|
+
- lib/dressmaker.rb
|
30
|
+
- lib/dressmaker/configuration.rb
|
31
|
+
- lib/dressmaker/configuration/directory_rule.rb
|
32
|
+
- spec/fixtures/template-test/Pattern
|
33
|
+
- spec/fixtures/template-test/bin/runner
|
34
|
+
- spec/fixtures/template-test/bin/script
|
35
|
+
- spec/generate_spec.rb
|
36
|
+
- spec/spec.opts
|
37
|
+
- spec/spec_helper.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/joshbuddy/dressmaker
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: dressmaker
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: Application templating in ruby. Define beautiful patterns and cut them out.
|
66
|
+
test_files:
|
67
|
+
- spec/generate_spec.rb
|
68
|
+
- spec/spec_helper.rb
|