Class: Template::Spec
- Inherits:
-
Object
- Object
- Template::Spec
- Defined in:
- lib/template/spec.rb
Instance Attribute Summary collapse
-
#block_actions_under_git ⇒ Object
Returns the value of attribute block_actions_under_git.
-
#identifier ⇒ Object
Returns the value of attribute identifier.
-
#post_actions ⇒ Object
Returns the value of attribute post_actions.
-
#required_files ⇒ Object
readonly
Returns the value of attribute required_files.
Class Method Summary collapse
- .expand_identifier(template_identifier) ⇒ Object
- .from_file(path) ⇒ Object
- .hash_for_spec_path(spec_path) ⇒ Object
- .hash_to_identifier(template_hash) ⇒ Object
- .identifier_is_ambiguous(identifier) ⇒ Object
- .spec_path_for_identifier(identifier) ⇒ Object
- .specs_matching_identifier(identifier) ⇒ Object
Instance Method Summary collapse
- #[](name) ⇒ Object
- #[]=(name, token) ⇒ Object
- #confirm_required_files ⇒ Object
- #each ⇒ Object
- #from_string(string, path) ⇒ Object
-
#initialize ⇒ Spec
constructor
A new instance of Spec.
- #invalidate(message) ⇒ Object
- #klippfile ⇒ Object
- #klippspec ⇒ Object
- #post_action=(action) ⇒ Object
- #pre_action=(action) ⇒ Object
- #pre_actions ⇒ Object
- #pre_actions=(pre_actions) ⇒ Object
- #replace_tokens(string_with_tokens, delimiter = 'XX') ⇒ Object
- #required_file(name, &config) ⇒ Object
- #set_token_values(tokens, verbose = false) ⇒ Object
-
#spec(identifier, &config) ⇒ Object
This method is called from the klippspec.
- #target_file(source_dir, source_file, target_dir) ⇒ Object
- #token(identifier, &config) ⇒ Object
- #transfer_file(source_file, target_file, overwrite) ⇒ Object
- #validate_spec ⇒ Object
Constructor Details
#initialize ⇒ Spec
Returns a new instance of Spec.
53 54 55 56 57 58 59 60 |
# File 'lib/template/spec.rb', line 53 def initialize @tokens = Hash[] @required_files = Array.new self[:BLANK] = Template::Token.new('', true) self[:DATE] = Template::Token.new(DateTime.now.strftime('%F'), true) self[:YEAR] = Template::Token.new(DateTime.now.strftime('%Y'), true) end |
Instance Attribute Details
#block_actions_under_git ⇒ Object
Returns the value of attribute block_actions_under_git.
8 9 10 |
# File 'lib/template/spec.rb', line 8 def block_actions_under_git @block_actions_under_git end |
#identifier ⇒ Object
Returns the value of attribute identifier.
8 9 10 |
# File 'lib/template/spec.rb', line 8 def identifier @identifier end |
#post_actions ⇒ Object
Returns the value of attribute post_actions.
9 10 11 |
# File 'lib/template/spec.rb', line 9 def post_actions @post_actions end |
#required_files ⇒ Object (readonly)
Returns the value of attribute required_files.
9 10 11 |
# File 'lib/template/spec.rb', line 9 def required_files @required_files end |
Class Method Details
.expand_identifier(template_identifier) ⇒ Object
41 42 43 44 45 |
# File 'lib/template/spec.rb', line 41 def self.(template_identifier) path = spec_path_for_identifier template_identifier hash = hash_for_spec_path path hash_to_identifier hash end |
.from_file(path) ⇒ Object
47 48 49 50 51 |
# File 'lib/template/spec.rb', line 47 def self.from_file(path) string = IO.read path spec = Template::Spec.new spec.from_string(string, path) end |
.hash_for_spec_path(spec_path) ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/template/spec.rb', line 29 def self.hash_for_spec_path(spec_path) relative_spec = spec_path.gsub(Klipp::Configuration.root_dir, '') { name: File.basename(spec_path, '.klippspec'), repo: relative_spec.split(File::SEPARATOR).map { |x| x=="" ? File::SEPARATOR : x }[1..-1].first } end |
.hash_to_identifier(template_hash) ⇒ Object
37 38 39 |
# File 'lib/template/spec.rb', line 37 def self.hash_to_identifier(template_hash) "#{template_hash[:repo]}/#{template_hash[:name]}" end |
.identifier_is_ambiguous(identifier) ⇒ Object
11 12 13 |
# File 'lib/template/spec.rb', line 11 def self.identifier_is_ambiguous(identifier) specs_matching_identifier(identifier).count == 1 end |
.spec_path_for_identifier(identifier) ⇒ Object
22 23 24 25 26 27 |
# File 'lib/template/spec.rb', line 22 def self.spec_path_for_identifier(identifier) specs = specs_matching_identifier identifier raise "Unknown template: #{identifier}. Use `klipp template list` to see your options" unless specs && specs.count > 0 raise "Found multiple templates named #{identifier}, use a full template identifier to pick one. Run `klipp template list` to see your options" if specs && specs.count > 1 specs.first end |
.specs_matching_identifier(identifier) ⇒ Object
15 16 17 18 19 20 |
# File 'lib/template/spec.rb', line 15 def self.specs_matching_identifier(identifier) chunks = identifier.split(File::SEPARATOR) name = chunks.pop repo = chunks.count > 0 ? File.join(chunks.pop, '**') : '**' Dir.glob(File.join(Klipp::Configuration.root_dir, repo, "#{name}.klippspec")) end |
Instance Method Details
#[](name) ⇒ Object
113 114 115 |
# File 'lib/template/spec.rb', line 113 def [](name) @tokens[name] end |
#[]=(name, token) ⇒ Object
117 118 119 120 |
# File 'lib/template/spec.rb', line 117 def []=(name, token) raise "Redeclaring tokens not allowed: #{name}" if @tokens[name] @tokens[name] = token end |
#confirm_required_files ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/template/spec.rb', line 158 def confirm_required_files() missing_files = Array.new self.required_files.each do |required_file| file_path = self.replace_tokens File.join(required_file.directory, required_file.name) FileUtils.mkdir_p File.dirname(file_path) missing_files << required_file unless File.exists? file_path end if missing_files.length > 0 = "Required file#{missing_files.length > 1 ? 's' : ''} not found:\n\n" missing_files.each do |missing_file| file_path = self.replace_tokens File.join(missing_file.directory, missing_file.name) << "\t#{file_path} - #{missing_file.comment ? "#{missing_file.comment}" : ''}\n" end raise end end |
#each ⇒ Object
180 181 182 |
# File 'lib/template/spec.rb', line 180 def each @tokens.each { |name, token| yield(name, token) } end |
#from_string(string, path) ⇒ Object
86 87 88 89 90 91 92 93 |
# File 'lib/template/spec.rb', line 86 def from_string(string, path) begin eval(string, nil, path) rescue Exception => e raise "Error evaluating spec: #{File.basename(path)}: #{e.}\n #{e.backtrace.join("\n ")}" end validate_spec end |
#invalidate(message) ⇒ Object
176 177 178 |
# File 'lib/template/spec.rb', line 176 def invalidate() raise end |
#klippfile ⇒ Object
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/template/spec.rb', line 191 def klippfile kf = "create '#{self.class.(self.identifier)}' do |tokens|\n\n" @tokens.each do |name, token| unless token.hidden kf += " # #{token.comment}\n" if token.comment kf += " # #{token.validation_hint}\n" if token.validation_hint if token.type == :bool kf += " tokens[:#{name}] = #{token.default_value ? 'true' : 'false'}\n" else kf += " tokens[:#{name}] = \"#{token.default_value}\"\n" end kf += "\n" end end kf += "end" end |
#klippspec ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
# File 'lib/template/spec.rb', line 208 def klippspec ks = "# encoding=utf-8\n" ks += "\n" ks += "spec '#{identifier}' do |s|\n" ks += " s.block_actions_under_git = true\n" ks += " # s.pre_actions = ['echo \"Hello klipp!\"']\n" ks += " # s.post_actions = ['pod install']\n" ks += "\n" ks += " s.token :REPLACEABLE do |t|\n" ks += " t.comment = \"Replaceable value (to insert in any filename or string containing 'XXREPLACEABLEXX')\"\n" ks += " t.validation = /^[A-Z][A-Za-z0-9 ]{2,}$/\n" ks += " t.validation_hint = 'At least three characters long, start with a capital character, may contain spaces'\n" ks += " end\n" ks += "\n" ks += " s.token :TOGGLE do |t|\n" ks += " t.comment = \"Toggle value (to insert in any filename or string containing 'XXTOGGLEXX')\"\n" ks += " t.type = :bool\n" ks += " # t.bool_strings = ['NO','YES']\n" ks += " end\n" ks += "\n" ks += " # ...\n" ks += "\n" ks += "end\n" end |
#post_action=(action) ⇒ Object
62 63 64 |
# File 'lib/template/spec.rb', line 62 def post_action=(action) post_actions << action end |
#pre_action=(action) ⇒ Object
74 75 76 |
# File 'lib/template/spec.rb', line 74 def pre_action=(action) pre_actions << action end |
#pre_actions ⇒ Object
78 79 80 |
# File 'lib/template/spec.rb', line 78 def pre_actions @pre_actions ||= [] end |
#pre_actions=(pre_actions) ⇒ Object
82 83 84 |
# File 'lib/template/spec.rb', line 82 def pre_actions=(pre_actions) @pre_actions = pre_actions.is_a?(Array) ? pre_actions : [pre_actions.to_s] end |
#replace_tokens(string_with_tokens, delimiter = 'XX') ⇒ Object
262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/template/spec.rb', line 262 def replace_tokens(string_with_tokens, delimiter='XX') unless string_with_tokens.valid_encoding? raise "Invalid string encoding #{string_with_tokens.encoding}" end replaced = string_with_tokens @tokens.each do |name, token| needle = delimiter+name.to_s+delimiter replacement = token.to_s replaced.gsub!(needle, replacement) end replaced end |
#required_file(name, &config) ⇒ Object
184 185 186 187 188 189 |
# File 'lib/template/spec.rb', line 184 def required_file name, &config required_file = Template::RequiredFile.new name raise 'Incomplete file configuration' unless block_given? config.yield(required_file) @required_files << required_file end |
#set_token_values(tokens, verbose = false) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/template/spec.rb', line 128 def set_token_values(tokens, verbose=false) token_errors = Hash[] puts() if verbose tokens.each do |name, value| token = self[name] begin if token Formatador.display_line("#{name}: [bold]#{value}[/]") if verbose token.value = value else token_errors[name] = "unanticipated token encountered in the Klippfile :#{name}" end rescue Exception => e token_errors[name] = "token :#{name}. #{e.}" end end @tokens.each do |name, token| token_errors[name] = "missing value for token :#{name}" if token.value == nil && token_errors[name] == nil end if token_errors.length > 0 msg = "Token configuration error:\n\n\t" msg << token_errors.map { |name, | }.join("\n\t") invalidate msg end puts() if verbose end |
#spec(identifier, &config) ⇒ Object
This method is called from the klippspec
96 97 98 99 100 101 102 103 104 |
# File 'lib/template/spec.rb', line 96 def spec identifier, &config self.identifier = identifier begin config.yield(self) if (block_given?) rescue Exception => e raise "Invalid klippspec configuration: #{e.}\n #{e.backtrace.join("\n ")}" end validate_spec end |
#target_file(source_dir, source_file, target_dir) ⇒ Object
233 234 235 236 237 |
# File 'lib/template/spec.rb', line 233 def target_file(source_dir, source_file, target_dir) stripped_path = source_file.gsub(source_dir, '') customizable_path = replace_tokens(stripped_path) File.join(target_dir, customizable_path) end |
#token(identifier, &config) ⇒ Object
106 107 108 109 110 111 |
# File 'lib/template/spec.rb', line 106 def token identifier, &config token = Template::Token.new raise 'Incomplete token configuration' unless block_given? config.yield(token) self[identifier] = token end |
#transfer_file(source_file, target_file, overwrite) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/template/spec.rb', line 239 def transfer_file(source_file, target_file, overwrite) FileUtils.mkdir_p File.dirname(target_file) if File.directory? source_file FileUtils.mkdir_p target_file elsif !File.exists?(target_file) || overwrite if File.binary? source_file FileUtils.cp(source_file, target_file) else FileUtils.cp(source_file, target_file) begin IO.write target_file, replace_tokens(File.read(source_file)) rescue # nothing end end else raise "#{target_file} already exists, not overwriting. Use -f to force overwriting." end target_file end |
#validate_spec ⇒ Object
122 123 124 125 126 |
# File 'lib/template/spec.rb', line 122 def validate_spec msg = 'Template configuration invalid: ' invalidate msg+'missing name' unless @identifier && @identifier.length > 0 self end |