templatron 0.1.2 → 0.2.0
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.
- checksums.yaml +4 -4
- data/lib/templatron/cli.rb +53 -62
- data/lib/templatron/collector.rb +96 -0
- data/lib/templatron/config.rb +21 -0
- data/lib/templatron/generator.rb +51 -22
- data/lib/templatron/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 00b8850a510c189094e5761a68649d231319d9ec
|
4
|
+
data.tar.gz: 8736415297d84d92655d62e5e881d256e5eddb59
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6b63bf41e826cf3862b3f4031bc5b74484bb16d8e7f168136b86a16ed32277b5437e73e1eee19bd356f9d3d98d8034948b80a4672061580719fdd5256a8af69
|
7
|
+
data.tar.gz: d70378ea9c97efff778e180e9e3272686b43acb022060a3745cdd0044e18f29254ccf2d2cba29fc6feea39b7877fc5fb0481f2b8dff2c912c28b0bdb4f40dc0a
|
data/lib/templatron/cli.rb
CHANGED
@@ -1,80 +1,71 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require 'clamp'
|
2
3
|
require 'templatron/version'
|
3
4
|
require 'templatron/config'
|
4
5
|
require 'templatron/generator'
|
5
|
-
require '
|
6
|
-
require 'ostruct'
|
6
|
+
require 'templatron/collector'
|
7
7
|
|
8
8
|
module Templatron
|
9
9
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
if ARGV.length == 0
|
17
|
-
puts usage
|
18
|
-
exit
|
10
|
+
# Represents a base class with command flags
|
11
|
+
class AbstractCommand < Clamp::Command
|
12
|
+
option ['-v', '--verbose'], :flag, 'Enable verbose mode', :default => false
|
13
|
+
option '--version', :flag, 'Show the current version' do
|
14
|
+
puts Templatron::VERSION
|
15
|
+
exit(0)
|
19
16
|
end
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# Defines options parser
|
28
|
-
opt_parser = OptionParser.new do |opts|
|
29
|
-
opts.banner = usage
|
30
|
-
opts.default_argv = '-h'
|
31
|
-
|
32
|
-
opts.separator ''
|
33
|
-
opts.separator 'Features:'
|
34
|
-
|
35
|
-
# Defines where to put generated files
|
36
|
-
opts.on('-o', '--output PATH', 'Where to put the generated files') do |dir|
|
37
|
-
options.output_dir = dir
|
38
|
-
end
|
39
|
-
|
40
|
-
# Should we remove the output directory first
|
41
|
-
opts.on('-d', '--delete', 'If set, clear the output directory first') do
|
42
|
-
options.delete_dir = true
|
43
|
-
end
|
44
|
-
|
45
|
-
opts.separator ''
|
46
|
-
opts.separator 'Common options:'
|
19
|
+
# Use to list the template dir
|
20
|
+
class ListCommand < AbstractCommand
|
21
|
+
parameter '[SUB_PATH]', 'Relative path to list from',
|
22
|
+
:attribute_name => :subpath,
|
23
|
+
:default => ''
|
24
|
+
option ['-a', '--all'], :flag, 'Also show files', :default => false
|
47
25
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
26
|
+
def execute
|
27
|
+
col = Collector.new(subpath, all?, false, verbose?)
|
28
|
+
entries = col.list
|
52
29
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
puts ''
|
57
|
-
puts "Templates path: #{Templatron::templates_path}"
|
58
|
-
exit
|
59
|
-
end
|
30
|
+
entries.each { |e| puts e.sub(col.full_path, '') }
|
31
|
+
end
|
32
|
+
end
|
60
33
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
34
|
+
# Use to build stuff!
|
35
|
+
class BuildCommand < AbstractCommand
|
36
|
+
parameter 'TEMPLATE_NAME', 'Template to generate from',
|
37
|
+
:attribute_name => :template
|
38
|
+
parameter '[ARGS] ...', 'Template arguments',
|
39
|
+
:attribute_name => :arguments
|
40
|
+
option ['-o', '--output'], 'OUTPUT_DIR', 'Where to put the generated files',
|
41
|
+
:default => Dir.pwd
|
42
|
+
option ['-d', '--delete'], :flag, 'Clear the output folder first',
|
43
|
+
:default => false
|
44
|
+
|
45
|
+
def execute
|
46
|
+
# Instantiate the generator and build the stuff
|
47
|
+
gen = Generator.new(
|
48
|
+
template,
|
49
|
+
arguments,
|
50
|
+
output,
|
51
|
+
delete?,
|
52
|
+
verbose?)
|
53
|
+
t_start = Time.now
|
54
|
+
gen.build
|
55
|
+
t_end = Time.now
|
56
|
+
puts "BUILT in #{t_end - t_start} seconds"
|
66
57
|
end
|
58
|
+
end
|
67
59
|
|
68
|
-
|
60
|
+
# Entry point of the cli
|
61
|
+
class MainCommand < AbstractCommand
|
62
|
+
subcommand 'build', 'Build from templates', BuildCommand
|
63
|
+
subcommand 'list', 'List available templates', ListCommand
|
64
|
+
end
|
69
65
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
ARGV[1..ARGV.length],
|
74
|
-
options.output_dir,
|
75
|
-
options.delete_dir,
|
76
|
-
options.verbose)
|
77
|
-
gen.build
|
66
|
+
# Public: CLI Stuff, parse command line inputs to determine what to do
|
67
|
+
def self.execute
|
68
|
+
MainCommand.run
|
78
69
|
end
|
79
70
|
|
80
71
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'templatron/config'
|
3
|
+
|
4
|
+
module Templatron
|
5
|
+
|
6
|
+
# Collector stuff
|
7
|
+
# Show templates and related informations
|
8
|
+
class Collector
|
9
|
+
|
10
|
+
attr_accessor :full_path
|
11
|
+
|
12
|
+
# Public: Initialize the collector instance
|
13
|
+
#
|
14
|
+
# path - Relative path of a template
|
15
|
+
# include_files - Also include files or not
|
16
|
+
# include_sub - Incluse subfolders?
|
17
|
+
# verbose - Verbose mode?
|
18
|
+
def initialize(path, include_files, include_sub, verbose = false)
|
19
|
+
@full_path = File.join(Templatron::templates_path, expand_path(path))
|
20
|
+
@verbose = verbose
|
21
|
+
@include_files = include_files
|
22
|
+
@include_subfolders = include_sub
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: List the content of this template
|
26
|
+
#
|
27
|
+
# Returns the list of entries for this instance
|
28
|
+
def list
|
29
|
+
puts "Listing content: of directory #{@full_path}" if @verbose
|
30
|
+
|
31
|
+
v = ['**']
|
32
|
+
v << '*' if @include_subfolders
|
33
|
+
|
34
|
+
entries = Dir.glob(escape_glob(File.join(@full_path, v)))
|
35
|
+
entries.map! { |e| e if File.directory?(e) }.compact! if !@include_files
|
36
|
+
|
37
|
+
entries
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
# Internal: Escape special characters, needed for glob to work
|
43
|
+
#
|
44
|
+
# str - String to escape
|
45
|
+
#
|
46
|
+
# Returns an escaped string
|
47
|
+
def escape_glob(str)
|
48
|
+
str.gsub(/[\\\{\}\[\]\?]/) { |x| "\\"+x }
|
49
|
+
end
|
50
|
+
|
51
|
+
# Internal: Expand the path by looking in each subfolders and replacing default
|
52
|
+
# placeholder values with their real names
|
53
|
+
#
|
54
|
+
# Notes
|
55
|
+
# It may need a little refactoring
|
56
|
+
#
|
57
|
+
# path - Path to expand
|
58
|
+
#
|
59
|
+
# Examples
|
60
|
+
#
|
61
|
+
# Given base/profile/authors, it will returns base/profile/{$1 authors}
|
62
|
+
#
|
63
|
+
# Returns the real path
|
64
|
+
def expand_path(path)
|
65
|
+
tmp = path
|
66
|
+
final_path_components = []
|
67
|
+
|
68
|
+
until (p = File.split(tmp)).first == '.'
|
69
|
+
tmp = p.first
|
70
|
+
component = p.last
|
71
|
+
|
72
|
+
# Gets all entries in this folder
|
73
|
+
base_path = File.join(Templatron::templates_path, tmp)
|
74
|
+
|
75
|
+
Dir.glob(escape_glob(File.join(base_path, '*'))).each do |e|
|
76
|
+
next if !File.directory?(e) # Only process folders
|
77
|
+
|
78
|
+
e.scan(Templatron::PLACEHOLDER_REG).each do |match|
|
79
|
+
# Replace this component if it matches the user input
|
80
|
+
if component.include?(match[1])
|
81
|
+
component.sub!(match[1], e.match(Templatron::placeholder_block_reg(match[1])).to_s)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
final_path_components << component
|
87
|
+
end
|
88
|
+
|
89
|
+
final_path_components << p.last
|
90
|
+
|
91
|
+
File.join(final_path_components.reverse)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
data/lib/templatron/config.rb
CHANGED
@@ -4,8 +4,29 @@ module Templatron
|
|
4
4
|
# This part will be joined to the user Dir.home
|
5
5
|
PREFIX = '.templatron'
|
6
6
|
|
7
|
+
PLACEHOLDER_REG = /{\$(\d*)\W?([\w\s]*)}/
|
8
|
+
|
7
9
|
# Public: Retrieve the full path which stores templates
|
8
10
|
def self.templates_path
|
9
11
|
File.join(Dir.home, PREFIX)
|
10
12
|
end
|
13
|
+
|
14
|
+
# Public: Retrieve the placeholder reg for replacement
|
15
|
+
#
|
16
|
+
# match_i - Match key
|
17
|
+
#
|
18
|
+
# Returns the regex for replacement
|
19
|
+
def self.placeholder_reg(match_i)
|
20
|
+
/{\$#{match_i}\W?([\w\s]*)}/
|
21
|
+
end
|
22
|
+
|
23
|
+
# Public: Retrieve the placeholder reg block which contains
|
24
|
+
# the whole placeholder markup
|
25
|
+
#
|
26
|
+
# key - Key to look for
|
27
|
+
#
|
28
|
+
# Returns the regex needed to retrieve the whole placeholder markup
|
29
|
+
def self.placeholder_block_reg(key)
|
30
|
+
/({\$\d*\W?[#{key}]*})/
|
31
|
+
end
|
11
32
|
end
|
data/lib/templatron/generator.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require '
|
2
|
+
require 'fileutils'
|
3
3
|
require 'templatron/config'
|
4
|
+
require 'templatron/collector'
|
4
5
|
|
5
6
|
module Templatron
|
6
7
|
|
@@ -20,7 +21,8 @@ module Templatron
|
|
20
21
|
@output = File.expand_path(output_dir)
|
21
22
|
@verbose = verbose
|
22
23
|
@clear = delete_dir
|
23
|
-
|
24
|
+
|
25
|
+
@collector = Collector.new(@template, true, true)
|
24
26
|
|
25
27
|
process_raw_arguments(args)
|
26
28
|
end
|
@@ -28,7 +30,7 @@ module Templatron
|
|
28
30
|
# Public: Effectively process a template to generate it
|
29
31
|
def build
|
30
32
|
# Check template existence
|
31
|
-
if !check_template_dir(@
|
33
|
+
if !check_template_dir(@collector.full_path)
|
32
34
|
puts "The template #{@template} does not appear to exist in #{@full_template_path}"
|
33
35
|
exit
|
34
36
|
end
|
@@ -36,28 +38,45 @@ module Templatron
|
|
36
38
|
# If sets, remove the output folder first
|
37
39
|
if @clear
|
38
40
|
puts "Clearing #{@output}" if @verbose
|
39
|
-
|
41
|
+
begin
|
42
|
+
FileUtils.remove_dir(@output)
|
43
|
+
rescue => ex
|
44
|
+
puts """Could not clear the folder, maybe someone is accessing it?
|
45
|
+
|
46
|
+
#{ex.message}
|
47
|
+
"""
|
48
|
+
exit(1)
|
49
|
+
end
|
40
50
|
end
|
41
51
|
|
42
52
|
# Print details if verbose is on
|
43
53
|
if @verbose
|
44
|
-
puts "Starting building #{@
|
45
|
-
puts "With:"
|
54
|
+
puts "Starting building #{@collector.full_path} to #{@output}"
|
55
|
+
puts "With:" if !@arguments.empty?
|
46
56
|
@arguments.each_with_index do |arg, i|
|
47
57
|
puts "\t{$#{i}} => #{arg}" if !arg.nil?
|
48
58
|
end
|
49
59
|
end
|
50
60
|
|
51
|
-
# And then process each files/folder
|
52
|
-
collect_str = File.join(@full_template_path, '**', '*')
|
53
|
-
# At this point, all file entries have been collected
|
54
|
-
entries = Dir[collect_str].map { |p| p if File.file?(p) }.compact
|
55
61
|
# So process them right now
|
56
|
-
process_files(
|
62
|
+
process_files(@collector.list)
|
57
63
|
end
|
58
64
|
|
59
65
|
protected
|
60
66
|
|
67
|
+
# Internal: Try to create a directory and fails gracefuly
|
68
|
+
def create_directory(path)
|
69
|
+
begin
|
70
|
+
FileUtils.mkdir_p(path)
|
71
|
+
rescue => ex
|
72
|
+
puts """Error while creating the directory #{path}
|
73
|
+
|
74
|
+
#{ex.message}
|
75
|
+
"""
|
76
|
+
exit(1)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
61
80
|
# Internal: Process each entries, copy the files and replaces variables
|
62
81
|
#
|
63
82
|
# entries - An array of files to process
|
@@ -65,23 +84,30 @@ module Templatron
|
|
65
84
|
entries.each do |path|
|
66
85
|
|
67
86
|
# Get base path
|
68
|
-
new_path = path.
|
87
|
+
new_path = path.sub(@collector.full_path, '')
|
69
88
|
|
89
|
+
is_dir = File.directory?(path)
|
90
|
+
|
70
91
|
# Apply arguments to the path
|
71
92
|
apply_arguments!(new_path)
|
72
93
|
|
73
|
-
# Now we can copy the entry
|
74
94
|
full_new_path = File.join(@output, new_path)
|
75
95
|
|
76
|
-
|
96
|
+
if is_dir
|
97
|
+
puts "Creating directory #{path} to #{full_new_path}" if @verbose
|
98
|
+
create_directory(full_new_path)
|
99
|
+
else
|
100
|
+
# Now we can copy the entry
|
101
|
+
puts "Copying #{path} to #{full_new_path}" if @verbose
|
77
102
|
|
78
|
-
|
79
|
-
|
103
|
+
create_directory(File.dirname(full_new_path))
|
104
|
+
FileUtils.copy(path, full_new_path)
|
80
105
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
106
|
+
file_content = File.read(full_new_path)
|
107
|
+
apply_arguments!(file_content)
|
108
|
+
File.open(full_new_path, 'w') do |f|
|
109
|
+
f.puts file_content
|
110
|
+
end
|
85
111
|
end
|
86
112
|
end
|
87
113
|
end
|
@@ -109,17 +135,20 @@ module Templatron
|
|
109
135
|
#
|
110
136
|
# str - Where to look & replace
|
111
137
|
def apply_arguments!(str)
|
112
|
-
str.scan(
|
138
|
+
str.scan(Templatron::PLACEHOLDER_REG).each do |match|
|
113
139
|
match_i = match[0].to_i
|
114
140
|
arg_value = @arguments[match_i]
|
115
141
|
arg_value = match[1] if arg_value.nil?
|
116
|
-
|
142
|
+
|
143
|
+
str.gsub!(Templatron::placeholder_reg(match_i), arg_value)
|
117
144
|
end
|
118
145
|
end
|
119
146
|
|
120
147
|
# Internal: Check if the template directory exists
|
121
148
|
#
|
122
149
|
# dir - Where to look
|
150
|
+
#
|
151
|
+
# Returns true if the directory exists, false otherwise
|
123
152
|
def check_template_dir(dir)
|
124
153
|
Dir.exist?(dir)
|
125
154
|
end
|
data/lib/templatron/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: templatron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Leicher
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Defines templates with variables and generates whatever you want
|
14
14
|
email:
|
@@ -20,6 +20,7 @@ extra_rdoc_files: []
|
|
20
20
|
files:
|
21
21
|
- bin/templatron
|
22
22
|
- lib/templatron/cli.rb
|
23
|
+
- lib/templatron/collector.rb
|
23
24
|
- lib/templatron/config.rb
|
24
25
|
- lib/templatron/generator.rb
|
25
26
|
- lib/templatron/version.rb
|