directory_template 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,100 @@
1
+ README
2
+ ======
3
+
4
+
5
+ Summary
6
+ -------
7
+ Lets you generate directory structures from a template, optionally processing paths
8
+ (variables in the path) and contents (e.g., render ERB templates).
9
+
10
+ Features
11
+ --------
12
+
13
+ * Generate directories and files
14
+ * Use a directory structure as template, or store the template in a YAML file
15
+ * Interpolate variables in directory- and filenames
16
+ * Render ERB and Markdown templates
17
+ * Write & use your own processors
18
+
19
+
20
+ Installation
21
+ ------------
22
+ `gem install directory_template`
23
+
24
+
25
+ Usage
26
+ -----
27
+
28
+ The examples given below are working examples. The templates are part of the gem and can
29
+ be found in the directory 'examples'.
30
+
31
+ Create a template from an existing structure and materialize it (create directories &
32
+ files):
33
+
34
+ require 'directory_template'
35
+ variables = {
36
+ namespace: 'Namespace',
37
+ version: '1.2.3',
38
+ gem_name: 'gem-name',
39
+ require_name: 'require_name',
40
+ description: "The description",
41
+ summary: "The summary"
42
+ }
43
+ template = DirectoryTemplate.directory('examples/dir_gem_template')
44
+ template.materialize('new_project', variables: variables)
45
+
46
+ Create a template from a YAML file:
47
+
48
+ require 'directory_template'
49
+ variables = {
50
+ namespace: 'Namespace',
51
+ version: '1.2.3',
52
+ gem_name: 'gem-name',
53
+ require_name: 'require_name',
54
+ description: "The description",
55
+ summary: "The summary"
56
+ }
57
+ template = DirectoryTemplate.yaml_file('examples/yaml_gem_template.yaml')
58
+ template.materialize('new_project', variables: variables)
59
+
60
+
61
+ Description
62
+ -----------
63
+ DirectoryTemplate is a library which lets you generate directory structures and files
64
+ from a template structure. The template structure can be a real directory structure on
65
+ the filesystem, or it can be stored in a yaml file. Take a look at the examples directory
66
+ in the gem to get an idea, how a template can look.
67
+
68
+ When generating a new directory structure from a template, DirectoryTemplate will process
69
+ the pathname of each directory and file using the DirectoryTemplate#path_processor.
70
+ It will also process the contents of each file with all processors that apply to a given
71
+ file.
72
+ The standard path processor allows you to use `%{variables}` in pathnames. The gem comes
73
+ with a .erb (renders ERB templates) and .html.markdown processor (renders markdown to
74
+ html).
75
+ You can use the existing processors or define your own ones.
76
+
77
+ Also take a look at the {file:documentation/ContentProcessors.markdown Content Processors Guide}
78
+ and the {file:documentation/ContentProcessors.markdown Path Processors Guide}.
79
+
80
+
81
+ Links
82
+ -----
83
+
84
+ * [Online API Documentation](http://rdoc.info/github/apeiros/directory_template/)
85
+ * [Public Repository](https://github.com/apeiros/directory_template)
86
+ * [Bug Reporting](https://github.com/apeiros/directory_template/issues)
87
+ * [RubyGems Site](https://rubygems.org/gems/directory_template)
88
+
89
+
90
+ Credits
91
+ -------
92
+
93
+ * Daniel Schärli, for proofreading the docs
94
+
95
+
96
+ License
97
+ -------
98
+
99
+ You can use this code under the {file:LICENSE.txt BSD-2-Clause License}, free of charge.
100
+ If you need a different license, please ask the author.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../rake/lib', __FILE__))
2
+ Dir.glob(File.expand_path('../rake/tasks/**/*.{rake,task,rb}', __FILE__)) do |task_file|
3
+ begin
4
+ import task_file
5
+ rescue LoadError => e
6
+ warn "Failed to load task file #{task_file}"
7
+ warn " #{e.class} #{e.message}"
8
+ warn " #{e.backtrace.first}"
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "directory_template"
5
+ s.version = "1.0.0"
6
+ s.authors = "Stefan Rusterholz"
7
+ s.homepage = "https://github.com/apeiros/directory_template"
8
+ s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
9
+ Create directories from templates.
10
+ Existing directory structures, yaml files and ruby datastructures can all serve as
11
+ sources of a template.
12
+ Can preprocess pathnames and content.
13
+ Path- and ContentProcessors are exchangeable.
14
+ DESCRIPTION
15
+ s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
16
+ Create directories from templates, optionally preprocessing paths and contents.
17
+ SUMMARY
18
+ s.email = "stefan.rusterholz@gmail.com"
19
+
20
+ s.files =
21
+ Dir['bin/**/*'] +
22
+ Dir['lib/**/*'] +
23
+ Dir['rake/**/*'] +
24
+ Dir['examples/**/*'] +
25
+ Dir['documentation/**/*'] +
26
+ Dir['test/**/*'] +
27
+ Dir['*.gemspec'] +
28
+ %w[
29
+ Rakefile
30
+ README.markdown
31
+ ]
32
+
33
+ if File.directory?('bin') then
34
+ executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
35
+ s.executables = executables unless executables.empty?
36
+ end
37
+
38
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
39
+ s.rubygems_version = "1.3.1"
40
+ s.specification_version = 3
41
+ end
@@ -0,0 +1,19 @@
1
+ CONTENT PROCESSORS
2
+ ==================
3
+
4
+
5
+ Included Processors
6
+ -------------------
7
+
8
+ DirectoryTemplate comes with the following content processors:
9
+
10
+ * :erb - Renders files with the '.erb' Suffix as ERB Templates.
11
+ * :html\_to\_markdown - Renders markdown files to html. It is applied to all files which
12
+ have .html.markdown as suffix (only the .markdown will be dropped).
13
+
14
+
15
+ Rolling your own
16
+ ----------------
17
+
18
+ See {DirectoryTemplate::Processor} for informations on how to create a content processor.
19
+
@@ -0,0 +1,17 @@
1
+ PATH PROCESSORS
2
+ ===============
3
+
4
+
5
+ Included Processors
6
+ -------------------
7
+
8
+ DirectoryTemplate comes with a simple path processor, it just replaces variables in the
9
+ form of `%{variable_name}` within paths with the value in `variable_name`. It takes the
10
+ variables from :path_variables and :variables in the env (in that order).
11
+
12
+
13
+ Rolling your own
14
+ ----------------
15
+
16
+ See {DirectoryTemplate::Processor} for informations on how to create a path processor.
17
+ For a path processor, you'll leave the pattern argument to nil.
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = <%= gem_name.inspect %>
5
+ s.version = <%= version.to_s.inspect %>
6
+ s.authors = <%= author.inspect %>
7
+ s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
8
+ <%= description && description.gsub(/^/,' ').sub(/\n*\z/, "\n") %>
9
+ DESCRIPTION
10
+ s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
11
+ <%= summary && summary.gsub(/^/,' ').sub(/\n*\z/, "\n") %>
12
+ SUMMARY
13
+ s.email = <%= email.inspect %>
14
+
15
+ s.files =
16
+ Dir['bin/**/*'] +
17
+ Dir['lib/**/*'] +
18
+ Dir['rake/**/*'] +
19
+ Dir['test/**/*'] +
20
+ Dir['*.gemspec'] +
21
+ %w[
22
+ Rakefile
23
+ README.markdown
24
+ ]
25
+ if File.directory?('bin') then
26
+ executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
27
+ s.executables = executables unless executables.empty?
28
+ end
29
+
30
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
31
+ s.rubygems_version = "1.3.1"
32
+ s.specification_version = 3
33
+ end
@@ -0,0 +1,21 @@
1
+ README
2
+ ======
3
+
4
+
5
+ Summary
6
+ -------
7
+ <%= summary %>
8
+
9
+
10
+ Installation
11
+ ------------
12
+ `gem install <%= gem_name %>`
13
+
14
+
15
+ Usage
16
+ -----
17
+
18
+
19
+ Description
20
+ -----------
21
+ <%= description %>
@@ -0,0 +1,9 @@
1
+ This readme informs you about the purpose of the directories
2
+
3
+ PROJECT/bin: Executable files
4
+ PROJECT/documentation: Prosa documentation of your project
5
+ PROJECT/development: Ideas and other things relevant for developing
6
+ PROJECT/lib: Your ruby library files
7
+ PROJECT/rake/lib: Libraries that are not part of your library, but used by your rake tasks
8
+ PROJECT/rake/tasks: Your rake tasks, using either .rb, .task or .rake as suffix
9
+ PROJECT/test: The tests for your library
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../rake/lib', __FILE__))
2
+ Dir.glob(File.expand_path('../rake/tasks/**/*.{rake,task,rb}', __FILE__)) do |task_file|
3
+ begin
4
+ import task_file
5
+ rescue LoadError => e
6
+ warn "Failed to load task file #{task_file}"
7
+ warn " #{e.class} #{e.message}"
8
+ warn " #{e.backtrace.first}"
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rubygems/version' # newer rubygems use this
5
+ rescue LoadError
6
+ require 'gem/version' # older rubygems use this
7
+ end
8
+
9
+ module <%= namespace %>
10
+ Version = Gem::Version.new(<%= version.to_s.inspect %>)
11
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require '<%= require_name %>/version'
6
+
7
+
8
+
9
+ # <%= namespace.chomp %>
10
+ <%= description.gsub(/\n*\z/, '').gsub(/^/, '# ')+"\n" %>
11
+ module <%= namespace %>
12
+ end
@@ -0,0 +1,110 @@
1
+ '%{gem_name}':
2
+ 'bin':
3
+ '%{gem_name}.stop': ~
4
+ 'development': {}
5
+ 'documentation': {}
6
+ 'lib':
7
+ '%{require_name}':
8
+ 'version.rb.stop.erb': |
9
+ # encoding: utf-8
10
+
11
+ begin
12
+ require 'rubygems/version' # newer rubygems use this
13
+ rescue LoadError
14
+ require 'gem/version' # older rubygems use this
15
+ end
16
+
17
+ module <%= namespace %>
18
+ Version = Gem::Version.new(<%= version.to_s.inspect %>)
19
+ end
20
+ '%{require_name}.rb.stop.erb': |
21
+ # encoding: utf-8
22
+
23
+
24
+
25
+ require '<%= require_name %>/version'
26
+
27
+
28
+
29
+ # <%= namespace.chomp %>
30
+ <%= description.gsub(/\n*\z/, '').gsub(/^/, '# ')+"\n" %>
31
+ module <%= namespace %>
32
+ end
33
+ '%{gem_name}.gemspec.stop.erb': |
34
+ # encoding: utf-8
35
+
36
+ Gem::Specification.new do |s|
37
+ s.name = <%= gem_name.inspect %>
38
+ s.version = <%= version.to_s.inspect %>
39
+ s.authors = <%= author.inspect %>
40
+ s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
41
+ <%= description && description.gsub(/^/,' ').sub(/\n*\z/, "\n") %>
42
+ DESCRIPTION
43
+ s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
44
+ <%= summary && summary.gsub(/^/,' ').sub(/\n*\z/, "\n") %>
45
+ SUMMARY
46
+ s.email = <%= email.inspect %>
47
+
48
+ s.files =
49
+ Dir['bin/**/*'] +
50
+ Dir['lib/**/*'] +
51
+ Dir['rake/**/*'] +
52
+ Dir['test/**/*'] +
53
+ Dir['*.gemspec'] +
54
+ %w[
55
+ Rakefile
56
+ README.markdown
57
+ ]
58
+ if File.directory?('bin') then
59
+ executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
60
+ s.executables = executables unless executables.empty?
61
+ end
62
+
63
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
64
+ s.rubygems_version = "1.3.1"
65
+ s.specification_version = 3
66
+ end
67
+ 'Rakefile.stop': |
68
+ $LOAD_PATH.unshift(File.expand_path('../rake/lib', __FILE__))
69
+ Dir.glob(File.expand_path('../rake/tasks/**/*.{rake,task,rb}', __FILE__)) do |task_file|
70
+ begin
71
+ import task_file
72
+ rescue LoadError => e
73
+ warn "Failed to load task file #{task_file}"
74
+ warn " #{e.class} #{e.message}"
75
+ warn " #{e.backtrace.first}"
76
+ end
77
+ end
78
+ 'README_DIRECTORIES.stop': |
79
+ This readme informs you about the purpose of the directories
80
+
81
+ PROJECT/bin: Executable files
82
+ PROJECT/documentation: Prosa documentation of your project
83
+ PROJECT/development: Ideas and other things relevant for developing
84
+ PROJECT/lib: Your ruby library files
85
+ PROJECT/rake/lib: Libraries that are not part of your library, but used by your rake tasks
86
+ PROJECT/rake/tasks: Your rake tasks, using either .rb, .task or .rake as suffix
87
+ PROJECT/test: The tests for your library
88
+ 'README.markdown.stop.erb': |
89
+ README
90
+ ======
91
+
92
+
93
+ Summary
94
+ -------
95
+ <%= summary %>
96
+
97
+
98
+ Installation
99
+ ------------
100
+ `gem install <%= gem_name %>`
101
+
102
+
103
+ Usage
104
+ -----
105
+
106
+
107
+ Description
108
+ -----------
109
+ <%= description %>
110
+ 'test': {}
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require 'stringio'
6
+
7
+
8
+
9
+ class DirectoryTemplate
10
+
11
+ # BlankSlate provides an abstract base class with no predefined
12
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
13
+ # BlankSlate is useful as a base class when writing classes that
14
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
15
+ #
16
+ # === Copyright
17
+ #
18
+ # Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
19
+ # All rights reserved.
20
+ # Permission is granted for use, copying, modification, distribution,
21
+ # and distribution of modified versions of this work as long as the
22
+ # above copyright notice is included.
23
+ #
24
+ # Modified by Stefan Rusterholz (stefan.rusterholz@gmail.com)
25
+ class BlankSlate
26
+
27
+ # Hide the method named +name+ in the BlankSlate class. Don't
28
+ # hide +instance_eval+ or any method beginning with "__".
29
+ #
30
+ # @return [self]
31
+ def self.hide(name)
32
+ verbosity = $VERBOSE
33
+ stderr = $stderr
34
+ $VERBOSE = nil
35
+ $stderr = StringIO.new
36
+
37
+ methods = instance_methods.map(&:to_sym)
38
+ if methods.include?(name.to_sym) and
39
+ name !~ /^(__|instance_eval)/
40
+ @hidden_methods ||= {}
41
+ @hidden_methods[name.to_sym] = instance_method(name)
42
+ undef_method name
43
+ end
44
+
45
+ self
46
+ ensure
47
+ $VERBOSE = verbosity
48
+ $stderr = stderr
49
+ end
50
+
51
+ # @return [UnboundMethod] The method that was hidden.
52
+ def self.find_hidden_method(name)
53
+ @hidden_methods ||= {}
54
+ @hidden_methods[name] || superclass.find_hidden_method(name)
55
+ end
56
+
57
+ # Redefine a previously hidden method so that it may be called on a blank
58
+ # slate object.
59
+ #
60
+ # @return [self]
61
+ def self.reveal(name)
62
+ hidden_method = find_hidden_method(name)
63
+ fail "Don't know how to reveal method '#{name}'" unless hidden_method
64
+ define_method(name, hidden_method)
65
+
66
+ self
67
+ end
68
+
69
+ instance_methods.each { |m| hide(m) }
70
+ end
71
+ end
72
+
73
+
74
+
75
+ # @private
76
+ # Extensions to Object for DirectoryTemplate::BlankSlate.
77
+ # Since Ruby is very dynamic, methods added to the ancestors of
78
+ # {DirectoryTemplate::BlankSlate} after BlankSlate is defined will show up in the
79
+ # list of available BlankSlate methods. We handle this by defining a hook in the Object
80
+ # and Kernel classes that will hide any method defined after BlankSlate has been loaded.
81
+ #
82
+ module Kernel
83
+ class << self
84
+ # Preserve the original method
85
+ alias template_directory_blank_slate_method_added method_added
86
+ end
87
+
88
+ # @private
89
+ # Detect method additions to Kernel and remove them in the
90
+ # BlankSlate class.
91
+ def self.method_added(name)
92
+ result = template_directory_blank_slate_method_added(name)
93
+ return result if self != ::Kernel
94
+ DirectoryTemplate::BlankSlate.hide(name)
95
+ result
96
+ end
97
+ end
98
+
99
+ # @private
100
+ # Extensions to Object for DirectoryTemplate::BlankSlate.
101
+ # Since Ruby is very dynamic, methods added to the ancestors of
102
+ # {DirectoryTemplate::BlankSlate} after BlankSlate is defined will show up in the
103
+ # list of available BlankSlate methods. We handle this by defining a hook in the Object
104
+ # and Kernel classes that will hide any method defined after BlankSlate has been loaded.
105
+ #
106
+ class Object
107
+ class << self
108
+ # Preserve the original method
109
+ alias template_directory_blank_slate_method_added method_added
110
+ end
111
+
112
+ # @private
113
+ # Detect method additions to Object and remove them in the
114
+ # BlankSlate class.
115
+ def self.method_added(name)
116
+ result = template_directory_blank_slate_method_added(name)
117
+ return result if self != Object
118
+ DirectoryTemplate::BlankSlate.hide(name)
119
+ result
120
+ end
121
+
122
+ # @private
123
+ # See DirectoryTemplate::BlankSlate::find_hidden_method
124
+ # This just serves as a stopper/terminator of the lookup chain.
125
+ def self.find_hidden_method(name)
126
+ nil
127
+ end
128
+ end
129
+
130
+ # @private
131
+ # Extensions to Module for DirectoryTemplate::BlankSlate.
132
+ # Modules included into Object need to be scanned and have their instance methods removed
133
+ # from {DirectoryTemplate::BlankSlate}. In theory, modules included into Kernel would have
134
+ # to be removed as well, but a "feature" of Ruby prevents late includes into modules from
135
+ # being exposed in the first place.
136
+ #
137
+ class Module
138
+
139
+ # @private
140
+ # Preserve the original method
141
+ alias template_directory_blank_slate_method_added append_features
142
+
143
+ # @private
144
+ # Monkey patch to the append_features callback of Module, used to update the BlankSlate.
145
+ def append_features(mod)
146
+ result = template_directory_blank_slate_method_added(mod)
147
+ return result if mod != Object
148
+ instance_methods.each do |name|
149
+ DirectoryTemplate::BlankSlate.hide(name)
150
+ end
151
+ result
152
+ end
153
+ end