klipp 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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +48 -0
- data/Rakefile +1 -0
- data/bin/klipp +6 -0
- data/build_klipp.sh +6 -0
- data/klipp.gemspec +26 -0
- data/lib/klipp/buffered_output.rb +17 -0
- data/lib/klipp/configuration.rb +31 -0
- data/lib/klipp/parameter_list.rb +19 -0
- data/lib/klipp/project.rb +46 -0
- data/lib/klipp/template.rb +50 -0
- data/lib/klipp/token.rb +35 -0
- data/lib/klipp/version.rb +3 -0
- data/lib/klipp.rb +135 -0
- data/spec/fixtures/klipps/Example.klippfile +4 -0
- data/spec/fixtures/klipps/ExcessiveExample.klippfile +5 -0
- data/spec/fixtures/klipps/Generated.klippfile +11 -0
- data/spec/fixtures/klipps/LackingExample.klippfile +3 -0
- data/spec/fixtures/klipps/MalformedExample.klippfile +4 -0
- data/spec/fixtures/klipps/single-token.yml +5 -0
- data/spec/fixtures/templates/Example/RegularFileWithContents.txt +3 -0
- data/spec/fixtures/templates/Example/XXCLASS_PREFIXXXPrefixedFile.txt +3 -0
- data/spec/fixtures/templates/Example/XXPROJECT_IDXX/BinaryFile.png +0 -0
- data/spec/fixtures/templates/Example/XXPROJECT_IDXX/XXCLASS_PREFIXXXPrefixedFileInDirectory.txt +3 -0
- data/spec/fixtures/templates/Example.yml +29 -0
- data/spec/klipp/configuration_spec.rb +24 -0
- data/spec/klipp/project_spec.rb +46 -0
- data/spec/klipp/template_spec.rb +80 -0
- data/spec/klipp/token_spec.rb +86 -0
- data/spec/klipp_spec.rb +139 -0
- data/spec/spec_helper.rb +17 -0
- metadata +168 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7ad411833795ad014a927e4dc6851f5d4c2630d6
|
4
|
+
data.tar.gz: 85ae4b599bf421be5ec49b50ff4f9b7bc699585b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d3ef430e9e4110b425a3da45dfef5ab577e65d7c24f73aac7ca6c32c8c97beb4deb5b9956731bf9affd09d50788b5b090724633fa5862ff51fb89a2643dfc350
|
7
|
+
data.tar.gz: df73b6338e8583b51dc78a855b532eb5e429eada147258db201b3b4b12d3e4b3c7a71fe75e267e3ec36221c985a727d23d032a1783599fd1c5c6bf54fd234d4b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Eric-Paul Lecluse
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# Klipp
|
2
|
+
## Xcode templates for the rest of us.
|
3
|
+
|
4
|
+
Klipp is a command line gem for creating new (Xcode) projects from existing templates. Unlike Apple's private plist-based templating system, Klipp takes an existing Xcode project and creates a new project by copying and modifying an existing template project by your own specifications.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Install Klipp with RubyGems:
|
9
|
+
|
10
|
+
$ gem install klipp
|
11
|
+
|
12
|
+
Execute and read the usage instructions:
|
13
|
+
|
14
|
+
$ klipp
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Klipp creates a template repository in your home directory, at ~/.klipp/templates
|
19
|
+
A template consists of a directory and an accompanying Yaml file, e.g.:
|
20
|
+
|
21
|
+
TemplateA
|
22
|
+
TemplateA.yml
|
23
|
+
|
24
|
+
Once you have templates like these present, you can prepare a new instance of that project by executing:
|
25
|
+
|
26
|
+
$ klipp prepare TemplateA
|
27
|
+
|
28
|
+
This will create a TemplateA.klippfile in your current directory, for you to edit with your favorite text editor.
|
29
|
+
From there, customize your project and when happy with the results, run:
|
30
|
+
|
31
|
+
$ klipp create
|
32
|
+
|
33
|
+
This will create a new directory called TemplateA, that contains your new project.
|
34
|
+
|
35
|
+
## Known issues
|
36
|
+
|
37
|
+
* Creating templates is done manually, this will be automated
|
38
|
+
* Errors while parsing the .klippfile are not yet handled gracefully
|
39
|
+
* Highline support for on-the-fly creation of new projects is not yet enabled
|
40
|
+
* The root of newly created projects carries the same name as the template, this will be adjustable.
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/klipp
ADDED
data/build_klipp.sh
ADDED
data/klipp.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'klipp/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'klipp'
|
8
|
+
spec.version = Klipp::VERSION
|
9
|
+
spec.authors = ['Eric-Paul Lecluse']
|
10
|
+
spec.email = %w(e@epologee.com)
|
11
|
+
spec.description = 'Klipp, Xcode templates for the rest of us.'
|
12
|
+
spec.summary = "Klipp is a command line gem for creating new (Xcode) projects from existing templates. Unlike Apple's private plist-based templating system, Klipp takes an existing Xcode project and creates a new project by copying and modifying an existing template project by your own specifications."
|
13
|
+
spec.homepage = 'https://github.com/epologee/klipp'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = %w(lib)
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
spec.add_development_dependency 'highline'
|
24
|
+
spec.add_development_dependency 'ptools'
|
25
|
+
spec.add_development_dependency 'colored'
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Klipp
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
@@auto_create_dirs = false # set by the gem's binary
|
5
|
+
|
6
|
+
def self.auto_create_dirs
|
7
|
+
@@auto_create_dirs
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.auto_create_dirs= auto_create_dirs
|
11
|
+
@@auto_create_dirs = auto_create_dirs
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.auto_create(dir)
|
15
|
+
if auto_create_dirs && File.directory?(File.dirname dir) && !File.exists?(dir)
|
16
|
+
Dir.mkdir dir
|
17
|
+
end
|
18
|
+
dir
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.root_dir
|
22
|
+
auto_create File.join(Dir.home, '.klipp')
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.templates_dir
|
26
|
+
auto_create File.join(root_dir, 'templates')
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Klipp
|
2
|
+
class ParameterList < Array
|
3
|
+
def options
|
4
|
+
select { |x| x.to_s[0, 1] == '-' }
|
5
|
+
end
|
6
|
+
|
7
|
+
def arguments
|
8
|
+
self - options
|
9
|
+
end
|
10
|
+
|
11
|
+
#def splice_option(name)
|
12
|
+
# !!delete(name)
|
13
|
+
#end
|
14
|
+
|
15
|
+
def shift_argument
|
16
|
+
(arg = arguments[0]) && delete(arg)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'ptools'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Klipp
|
5
|
+
|
6
|
+
class Project
|
7
|
+
|
8
|
+
def initialize(template)
|
9
|
+
@template = template
|
10
|
+
end
|
11
|
+
|
12
|
+
def create
|
13
|
+
# Check template directory exists
|
14
|
+
# Copy all files while adjusting paths
|
15
|
+
source_template_dir = File.join(Klipp::Configuration.templates_dir, @template.name)
|
16
|
+
target_template_dir = File.join(Dir.pwd, @template.name)
|
17
|
+
|
18
|
+
raise "Target directory already exists. Klipp will not overwrite your project: #{target_template_dir}" if File.exists? target_template_dir
|
19
|
+
|
20
|
+
@source_files = Dir.glob(File.join(source_template_dir, '**', '*'))
|
21
|
+
@source_files.each do |source_file|
|
22
|
+
transfer_file source_file, target_file(source_template_dir, source_file, target_template_dir)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def target_file(source_template_dir, source_file, target_template_dir)
|
27
|
+
stripped_path = source_file.gsub(source_template_dir, '')
|
28
|
+
customizable_path = @template.replace_tokens(stripped_path)
|
29
|
+
File.join(target_template_dir, customizable_path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def transfer_file(source_file, target_file)
|
33
|
+
FileUtils.mkdir_p File.dirname(target_file)
|
34
|
+
|
35
|
+
if File.directory? source_file
|
36
|
+
FileUtils.mkdir_p target_file
|
37
|
+
elsif File.binary? source_file
|
38
|
+
FileUtils.cp(source_file, target_file)
|
39
|
+
else
|
40
|
+
IO.write target_file, @template.replace_tokens(File.read(source_file))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module Klipp
|
5
|
+
|
6
|
+
class Template
|
7
|
+
attr_reader :tokens, :name
|
8
|
+
|
9
|
+
def initialize path, name
|
10
|
+
@name = name
|
11
|
+
raise 'Attempted to initialize template without name' unless name
|
12
|
+
|
13
|
+
full_path = File.join(path, "#{name}.yml")
|
14
|
+
raise "Unknown template name: #{name} (in template directory #{path})" unless File.exists?(full_path)
|
15
|
+
yaml_tokens = YAML.load(File.read(full_path))
|
16
|
+
|
17
|
+
@tokens = Hash[yaml_tokens.map { |token_name, values| [token_name, Klipp::Token.new(values)] }]
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](name)
|
21
|
+
@tokens[name].value
|
22
|
+
end
|
23
|
+
|
24
|
+
def []=(name, value)
|
25
|
+
@tokens[name].value=value
|
26
|
+
end
|
27
|
+
|
28
|
+
def load_klippfile(klippfile)
|
29
|
+
yaml = YAML.load(File.read(klippfile))
|
30
|
+
raise 'Tokens not matching' unless yaml.keys == @tokens.keys
|
31
|
+
yaml.each { |name, value| self[name] = value }
|
32
|
+
end
|
33
|
+
|
34
|
+
def klippfile
|
35
|
+
"#{@name}.klippfile"
|
36
|
+
end
|
37
|
+
|
38
|
+
def generated_klippfile
|
39
|
+
@tokens.map { |name, t| "#{name}:\n# #{t.subtitle}" }.join("\n\n")
|
40
|
+
end
|
41
|
+
|
42
|
+
def replace_tokens(string_with_tokens, delimiter='XX')
|
43
|
+
replaced = string_with_tokens
|
44
|
+
@tokens.each { |name, t| replaced.gsub!(delimiter+name+delimiter, t.value ? t.value.to_s : '') }
|
45
|
+
replaced
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/lib/klipp/token.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Klipp
|
4
|
+
|
5
|
+
class Token
|
6
|
+
attr_accessor :value
|
7
|
+
attr_reader :title, :subtitle, :default, :validate, :not_valid_response
|
8
|
+
|
9
|
+
def initialize(token_yml)
|
10
|
+
if token_yml.is_a? String
|
11
|
+
parsed = YAML.load token_yml
|
12
|
+
else
|
13
|
+
parsed = token_yml
|
14
|
+
end
|
15
|
+
|
16
|
+
@title = parsed['title']
|
17
|
+
@subtitle = parsed['subtitle']
|
18
|
+
@default = parsed['default']
|
19
|
+
@validate = parsed['validate']
|
20
|
+
@not_valid_response = parsed['not_valid_response']
|
21
|
+
|
22
|
+
rescue Exception => e
|
23
|
+
p token_yml
|
24
|
+
end
|
25
|
+
|
26
|
+
def ask_for_input(terminal = nil)
|
27
|
+
@value = (terminal || HighLine.new).ask("\n<%= color('#{@title}', BOLD) %> #{"(#{@subtitle})" if @subtitle})?") do |q|
|
28
|
+
q.default = @default if @default
|
29
|
+
q.validate = @validate if @validate
|
30
|
+
q.responses[:not_valid] = @not_valid_response if @not_valid_response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/klipp.rb
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'klipp/buffered_output'
|
2
|
+
require 'klipp/version'
|
3
|
+
require 'klipp/configuration'
|
4
|
+
require 'klipp/token'
|
5
|
+
require 'klipp/template'
|
6
|
+
require 'klipp/parameter_list'
|
7
|
+
require 'klipp/project'
|
8
|
+
require 'colorize'
|
9
|
+
|
10
|
+
module Klipp
|
11
|
+
extend BufferedOutput::ClassMethods
|
12
|
+
|
13
|
+
def self.display_exception exception
|
14
|
+
if exception.is_a? HelpRequest
|
15
|
+
help = exception
|
16
|
+
else
|
17
|
+
help = HelpRequest.new exception.message, true
|
18
|
+
help.set_backtrace(exception.backtrace)
|
19
|
+
end
|
20
|
+
|
21
|
+
buffer_puts help.message
|
22
|
+
exit help.exit_status
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.route(*argv)
|
26
|
+
@params = Klipp::ParameterList.new(argv)
|
27
|
+
command = @params.shift_argument
|
28
|
+
case command
|
29
|
+
when 'version'
|
30
|
+
version
|
31
|
+
when 'list'
|
32
|
+
list
|
33
|
+
when 'prepare'
|
34
|
+
prepare @params.first
|
35
|
+
when 'create'
|
36
|
+
create @params.first
|
37
|
+
when nil
|
38
|
+
raise HelpRequest.new('Use one of the commands below to start with klipp.', false, true)
|
39
|
+
else
|
40
|
+
raise "Unknown command: #{command}"
|
41
|
+
end
|
42
|
+
|
43
|
+
rescue Exception => e
|
44
|
+
display_exception e
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.version
|
48
|
+
buffer_puts Klipp::VERSION
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.list
|
52
|
+
files = template_files
|
53
|
+
|
54
|
+
raise "No templates found. Create a template directory and .yml file in #{Klipp::Configuration.templates_dir}" unless files.length > 0
|
55
|
+
|
56
|
+
buffer_puts("Available templates for use with #{'klipp prepare'.yellow} or #{'klipp create'.yellow}:\n\n")
|
57
|
+
files.each do |file|
|
58
|
+
buffer_puts(" * #{File.basename(file, '.*').green}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.prepare(template_name)
|
63
|
+
raise HelpRequest.new 'Add a template name to the `prepare` command.' unless template_name
|
64
|
+
|
65
|
+
template = Klipp::Template.new(Klipp::Configuration.templates_dir, template_name)
|
66
|
+
raise "#{template.klippfile} already exists. Delete it if you want to prepare a new template." if File.exists? template.klippfile
|
67
|
+
IO.write(template.klippfile, template.generated_klippfile)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.create(template_name)
|
71
|
+
if template_name
|
72
|
+
klippfile = File.join(Dir.pwd, "#{template_name}.klippfile")
|
73
|
+
else
|
74
|
+
klippfile = Dir.glob(File.join(Dir.pwd, '*.klippfile')).first
|
75
|
+
template_name = File.basename(klippfile, File.extname(klippfile)) if klippfile
|
76
|
+
end
|
77
|
+
|
78
|
+
template = Klipp::Template.new(Klipp::Configuration.templates_dir, template_name)
|
79
|
+
|
80
|
+
if klippfile
|
81
|
+
# load token values from klippfile
|
82
|
+
template.load_klippfile klippfile
|
83
|
+
elsif template_name
|
84
|
+
# ask for token values with highline
|
85
|
+
raise "Direct user input not yet supported. Use #{'klipp prepare'.yellow} to prepare a .klippfile"
|
86
|
+
else
|
87
|
+
raise "Add a template name to the `create` command, or use #{'klipp prepare'.yellow} to prepare a .klippfile"
|
88
|
+
end
|
89
|
+
|
90
|
+
project = Klipp::Project.new(template)
|
91
|
+
project.create
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def self.template_files
|
97
|
+
Dir.glob File.join(Klipp::Configuration.templates_dir, '*.yml')
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
class HelpRequest < StandardError
|
103
|
+
def initialize(msg, unknown=false, show_title=false)
|
104
|
+
@unknown = unknown
|
105
|
+
@show_title = show_title
|
106
|
+
super(msg)
|
107
|
+
end
|
108
|
+
|
109
|
+
def message
|
110
|
+
if @unknown
|
111
|
+
"[!] #{super.to_s}".red+"\n\n#{commands}\n\n#{self.backtrace.join("\n")}"
|
112
|
+
else
|
113
|
+
"#{@show_title ? title+"\n\n" : ''}"+"[?] #{super.to_s}".yellow+"\n\n#{commands}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def title
|
118
|
+
"\033[1mKlipp\033[22m, Xcode templates for the rest of us. Version: #{Klipp::VERSION}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def commands
|
122
|
+
commands = [
|
123
|
+
version: 'Display the Klipp version number.',
|
124
|
+
list: "List all available klipp templates in #{Klipp::Configuration.templates_dir}",
|
125
|
+
prepare: 'Prepare a .klippfile to edit in your favorite text editor.',
|
126
|
+
create: 'Create a project based on the template name or .klippfile in the current directory'
|
127
|
+
]
|
128
|
+
command_list = commands.map { |cmd| cmd.map { |key, summary| " * klipp #{key.to_s.ljust(10).green} #{summary}" } }.join("\n")
|
129
|
+
"Commands:\n\n#{command_list}"
|
130
|
+
end
|
131
|
+
|
132
|
+
def exit_status
|
133
|
+
@unknown ? 2 : 1
|
134
|
+
end
|
135
|
+
end
|
Binary file
|
@@ -0,0 +1,29 @@
|
|
1
|
+
PARTNER:
|
2
|
+
title: Partner name
|
3
|
+
subtitle: e.g. 'FC Utrecht'
|
4
|
+
default: Qwerty
|
5
|
+
validate: !ruby/regexp '/^[A-Z][A-Za-z0-9 ]{2,}$/'
|
6
|
+
not_valid_response: Should be at least three characters long and start with a capital character
|
7
|
+
|
8
|
+
PROJECT_TITLE:
|
9
|
+
title: Project title
|
10
|
+
subtitle: e.g. 'FC Utrecht Agenda'
|
11
|
+
default: #PARTNER# Agenda
|
12
|
+
validate: !ruby/regexp '/^[A-Z][A-Za-z0-9 ]{2,}$/'
|
13
|
+
not_valid_response: Should be at least three characters long and start with a capital character
|
14
|
+
|
15
|
+
PROJECT_ID:
|
16
|
+
title: Project id
|
17
|
+
subtitle: e.g. 'FCUtrechtAgenda'
|
18
|
+
default: #PROJECT_ID#
|
19
|
+
whitespace: :strip_and_collapse
|
20
|
+
validate: !ruby/regexp '/^[A-Z][A-Za-z0-9 ]{2,}$/'
|
21
|
+
not_valid_response: Should be at least three characters long and start with a capital character
|
22
|
+
|
23
|
+
CLASS_PREFIX:
|
24
|
+
title: Class prefix
|
25
|
+
subtitle: e.g. 'FCU'
|
26
|
+
default: #PROJECT_ID#
|
27
|
+
whitespace: :strip_and_collapse
|
28
|
+
validate: !ruby/regexp '/^[A-Z][A-Za-z0-9 ]{2,}$/'
|
29
|
+
not_valid_response: Should be at least three characters long and start with a capital character
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
describe Klipp::Configuration do
|
5
|
+
|
6
|
+
it 'points to .klipp inside the user\'s home directory' do
|
7
|
+
Klipp::Configuration.root_dir.should eq File.join(Dir.home, '.klipp')
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'with auto create enabled' do
|
11
|
+
|
12
|
+
before do
|
13
|
+
Klipp::Configuration.auto_create_dirs = true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'auto creates the .klipp directory' do
|
17
|
+
Dir.expects(:mkdir).once
|
18
|
+
File.expects(:exists?).once.returns false
|
19
|
+
Klipp::Configuration.root_dir
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
describe Klipp::Project do
|
5
|
+
|
6
|
+
context 'with a template' do
|
7
|
+
|
8
|
+
before do
|
9
|
+
fixtures_dir = File.join(File.dirname(__dir__), 'fixtures')
|
10
|
+
Klipp::Configuration.stubs(:root_dir).returns fixtures_dir
|
11
|
+
@template = Klipp::Template.new(Klipp::Configuration.templates_dir, 'Example')
|
12
|
+
@template.load_klippfile File.join(fixtures_dir, 'klipps', 'Example.klippfile')
|
13
|
+
@project = Klipp::Project.new(@template)
|
14
|
+
Dir.stubs(:pwd).returns(Dir.mktmpdir)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'copies files while replacing paths' do
|
18
|
+
@project.create
|
19
|
+
File.exists?(File.join Dir.pwd, 'Example', 'ProjectX').should be true
|
20
|
+
File.exists?(File.join Dir.pwd, 'Example', 'PJXPrefixedFile.txt').should be true
|
21
|
+
File.exists?(File.join Dir.pwd, 'Example', 'ProjectX', 'BinaryFile.png').should be true
|
22
|
+
File.exists?(File.join Dir.pwd, 'Example', 'ProjectX', 'PJXPrefixedFileInDirectory.txt').should be true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'replaces file contens while transferring' do
|
26
|
+
@project.create
|
27
|
+
File.read(File.join Dir.pwd, 'Example', 'PJXPrefixedFile.txt').should include 'Regular content stays untouched'
|
28
|
+
File.read(File.join Dir.pwd, 'Example', 'PJXPrefixedFile.txt').should include 'Tokens are replaced: ProjectX'
|
29
|
+
File.read(File.join Dir.pwd, 'Example', 'PJXPrefixedFile.txt').should include 'Even if it\'s in the middle of something else BlablablaProjectXBlabla'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'copies binary files without replacing contents' do
|
33
|
+
@project.create
|
34
|
+
template_png = File.join(Klipp::Configuration.templates_dir, 'Example', 'XXPROJECT_IDXX', 'BinaryFile.png')
|
35
|
+
transferred_png = File.join(Dir.pwd, 'Example', 'ProjectX', 'BinaryFile.png')
|
36
|
+
FileUtils.compare_file(template_png, transferred_png).should be true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'halts transfer if the directory already exists' do
|
40
|
+
FileUtils.mkdir_p File.join(Dir.pwd, 'Example')
|
41
|
+
expect { @project.create }.to raise_error RuntimeError
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Klipp::Template do
|
4
|
+
|
5
|
+
it 'raises an error when initialized with an invalid path or name' do
|
6
|
+
expect {
|
7
|
+
Klipp::Template.new('bull', 'shit')
|
8
|
+
}.to raise_error(RuntimeError)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'with a valid path and name' do
|
12
|
+
|
13
|
+
before do
|
14
|
+
@templates_dir = File.join(__dir__, '..', 'fixtures', 'templates')
|
15
|
+
@klipps_dir = File.join(__dir__, '..', 'fixtures', 'klipps')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'initializes' do
|
19
|
+
Klipp::Template.new(@templates_dir, 'Example').should be_a Klipp::Template
|
20
|
+
end
|
21
|
+
|
22
|
+
xit 'validates the template yml' do
|
23
|
+
true.should eq false
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'with a template object' do
|
27
|
+
|
28
|
+
before do
|
29
|
+
@template = Klipp::Template.new(@templates_dir, 'Example')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'knows the name of the corresponding .klippfile' do
|
33
|
+
@template.klippfile.should eq 'Example.klippfile'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'can generate stubbed contents for a .klippfile' do
|
37
|
+
@template.generated_klippfile.should eq File.read(File.join(@klipps_dir,'Generated.klippfile'))
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'contains a matching number of tokens' do
|
41
|
+
@template.tokens.should have_exactly(4).items
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'loads the token values from a valid Klippfile' do
|
45
|
+
@template.load_klippfile File.join(@klipps_dir, 'Example.klippfile')
|
46
|
+
@template['PARTNER'].should eq 'The Prestigeous Partner'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises an error when the Klippfile is malformed' do
|
50
|
+
expect { @template.load_klippfile File.join(@klipps_dir, 'MalformedExample.klippfile') }.to raise_error RuntimeError
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises an error when the Klippfile contains excess tokens' do
|
54
|
+
expect { @template.load_klippfile File.join(@klipps_dir, 'ExcessiveExample.klippfile') }.to raise_error RuntimeError
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises an error when the Klippfile contains too few tokens' do
|
58
|
+
expect { @template.load_klippfile File.join(@klipps_dir, 'LackingExample.klippfile') }.to raise_error RuntimeError
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with a template object and token values' do
|
64
|
+
|
65
|
+
before do
|
66
|
+
@template = Klipp::Template.new(@templates_dir, 'Example')
|
67
|
+
@template['CLASS_PREFIX'] = 'PJX'
|
68
|
+
@template['PROJECT_ID'] = 'ProjectX'
|
69
|
+
@template['PROJECT_TITLE'] = 'Project X'
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'replaces delimited tokens in a string' do
|
73
|
+
@template.replace_tokens('XXCLASS_PREFIXXX XXPROJECT_IDXX XXPROJECT_TITLEXX').should eq 'PJX ProjectX Project X'
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'highline/import'
|
3
|
+
|
4
|
+
describe Klipp::Token do
|
5
|
+
|
6
|
+
context 'with a single token yaml' do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@token = Klipp::Token.new read_fixture('klipps/single-token.yml')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'has a title' do
|
13
|
+
@token.title.should eq 'Partner name'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has a subtitle' do
|
17
|
+
@token.subtitle.should eq "e.g. 'FC Utrecht'"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'has a default value' do
|
21
|
+
@token.default.should eq 'Qwerty'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'has a validate regex' do
|
25
|
+
@token.validate.should eq /^[A-Z][A-Za-z0-9 ]{2,}$/
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'has a response when not valid' do
|
29
|
+
@token.not_valid_response.should eq 'Should be at least three characters long and start with a capital character'
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with a valid token object' do
|
35
|
+
|
36
|
+
before do
|
37
|
+
@input = StringIO.new
|
38
|
+
@output = StringIO.new
|
39
|
+
@terminal = HighLine.new(@input, @output)
|
40
|
+
@token = Klipp::Token.new read_fixture('klipps/single-token.yml')
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'can ask a question' do
|
44
|
+
simulate_input 'Something'
|
45
|
+
|
46
|
+
@token.ask_for_input @terminal
|
47
|
+
|
48
|
+
@output.string.should include 'Partner name'
|
49
|
+
@output.string.should include "e.g. 'FC Utrecht'"
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'records the answer' do
|
53
|
+
name = 'Qwerty'
|
54
|
+
simulate_input name
|
55
|
+
|
56
|
+
@token.ask_for_input @terminal
|
57
|
+
|
58
|
+
@token.value.should eq name
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'uses highline validation' do
|
62
|
+
simulate_input 'Qw'
|
63
|
+
|
64
|
+
expect {
|
65
|
+
@token.ask_for_input @terminal
|
66
|
+
}.to raise_error(EOFError)
|
67
|
+
|
68
|
+
@output.string.should include 'Should be at least three characters long and start with a capital character'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'prefills a default value' do
|
72
|
+
simulate_input
|
73
|
+
|
74
|
+
@token.ask_for_input @terminal
|
75
|
+
|
76
|
+
@token.value.should eq 'Qwerty'
|
77
|
+
end
|
78
|
+
|
79
|
+
def simulate_input(value = '')
|
80
|
+
@input << value << "\n"
|
81
|
+
@input.rewind
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/spec/klipp_spec.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Klipp do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@output = Klipp.output = StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'when routing' do
|
11
|
+
|
12
|
+
it 'prints help without any parameters' do
|
13
|
+
expect { Klipp.route *%w[] }.to raise_error SystemExit
|
14
|
+
should include 'Xcode templates for the rest of us.'
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'prints warnings accordingly' do
|
18
|
+
expect { Klipp.route *%w[prepare Bullshit] }.to raise_error SystemExit
|
19
|
+
should include '[!]'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'raises a warning when routing unknown commands' do
|
23
|
+
expect { Klipp.route *%w[allyourbase] }.to raise_error SystemExit
|
24
|
+
should include '[!]'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'routes `prepare`' do
|
28
|
+
Klipp.expects(:prepare)
|
29
|
+
Klipp.route *%w[prepare Example]
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'prints help when preparing without a template name' do
|
33
|
+
expect { Klipp.route *%w[prepare] }.to raise_error SystemExit
|
34
|
+
should include 'Add a template name to the `prepare` command.'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'routes `list`' do
|
38
|
+
Klipp.expects(:list)
|
39
|
+
Klipp.route *%w[list]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'routes `version`' do
|
43
|
+
Klipp.expects(:version)
|
44
|
+
Klipp.route *%w[version]
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'routes `create``' do
|
48
|
+
Klipp.expects(:create)
|
49
|
+
Klipp.route *%w[create]
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'when preparing' do
|
55
|
+
|
56
|
+
before do
|
57
|
+
Klipp::Configuration.stubs(:root_dir).returns File.join(__dir__, 'fixtures')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'raises help if the template argument is missing' do
|
61
|
+
expect { Klipp.prepare nil }.to raise_error HelpRequest
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'saves a klippfile' do
|
65
|
+
IO.expects(:write).with('Example.klippfile', anything).once
|
66
|
+
Klipp.prepare 'Example'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'raises an error when the template argument is incorrect' do
|
70
|
+
expect { Klipp.prepare 'Bullshit' }.to raise_error RuntimeError
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'raises an error when a .klippfile for the template already exists' do
|
74
|
+
File.stubs(:exists?).with(anything).returns true
|
75
|
+
expect { Klipp.prepare 'Example' }.to raise_error RuntimeError
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe 'when listing' do
|
81
|
+
|
82
|
+
it 'lists templates' do
|
83
|
+
Klipp::Configuration.stubs(:root_dir).returns File.join(__dir__, 'fixtures')
|
84
|
+
Klipp.list
|
85
|
+
should include 'Example'
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'raises an error when there are no templates' do
|
89
|
+
Klipp.expects(:template_files).returns([])
|
90
|
+
expect { Klipp.list }.to raise_error RuntimeError
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe 'when versioning' do
|
96
|
+
|
97
|
+
it 'displays the current version' do
|
98
|
+
Klipp.version
|
99
|
+
should include Klipp::VERSION
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'when creating' do
|
105
|
+
|
106
|
+
before do
|
107
|
+
Klipp::Configuration.stubs(:root_dir).returns File.join(__dir__, 'fixtures')
|
108
|
+
@example_klippfile_contents = File.read(File.join(__dir__, 'fixtures', 'klipps', 'Example.klippfile'))
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'calls create on a project with a named template' do
|
112
|
+
mock_project = mock
|
113
|
+
mock_project.expects(:create)
|
114
|
+
Klipp::Project.expects(:new).with(is_a(Klipp::Template)).returns(mock_project)
|
115
|
+
File.stubs(:read).with(anything).returns( @example_klippfile_contents )
|
116
|
+
Klipp.create('Example')
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'calls create on a project with an inferred template' do
|
120
|
+
Dir.expects(:glob).with(anything, anything).returns %w(Example.klippfile)
|
121
|
+
mock_project = mock
|
122
|
+
mock_project.expects(:create)
|
123
|
+
Klipp::Project.expects(:new).with(is_a(Klipp::Template)).returns(mock_project)
|
124
|
+
File.stubs(:read).with(anything).returns( @example_klippfile_contents )
|
125
|
+
Klipp.create nil
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'raises an error when the template name can\'t be inferred' do
|
129
|
+
Dir.expects(:glob).with(anything, anything).returns []
|
130
|
+
expect { Klipp.create nil }.to raise_error RuntimeError
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
def subject
|
136
|
+
@output.string
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'coveralls'
|
3
|
+
require 'mocha/api'
|
4
|
+
|
5
|
+
SimpleCov.start
|
6
|
+
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
7
|
+
|
8
|
+
require 'klipp'
|
9
|
+
|
10
|
+
def read_fixture fixture_name
|
11
|
+
File.read(File.join(__dir__, 'fixtures', fixture_name))
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.mock_framework = :mocha
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: klipp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric-Paul Lecluse
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: highline
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ptools
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: colored
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Klipp, Xcode templates for the rest of us.
|
84
|
+
email:
|
85
|
+
- e@epologee.com
|
86
|
+
executables:
|
87
|
+
- klipp
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- bin/klipp
|
97
|
+
- build_klipp.sh
|
98
|
+
- klipp.gemspec
|
99
|
+
- lib/klipp.rb
|
100
|
+
- lib/klipp/buffered_output.rb
|
101
|
+
- lib/klipp/configuration.rb
|
102
|
+
- lib/klipp/parameter_list.rb
|
103
|
+
- lib/klipp/project.rb
|
104
|
+
- lib/klipp/template.rb
|
105
|
+
- lib/klipp/token.rb
|
106
|
+
- lib/klipp/version.rb
|
107
|
+
- spec/fixtures/klipps/Example.klippfile
|
108
|
+
- spec/fixtures/klipps/ExcessiveExample.klippfile
|
109
|
+
- spec/fixtures/klipps/Generated.klippfile
|
110
|
+
- spec/fixtures/klipps/LackingExample.klippfile
|
111
|
+
- spec/fixtures/klipps/MalformedExample.klippfile
|
112
|
+
- spec/fixtures/klipps/single-token.yml
|
113
|
+
- spec/fixtures/templates/Example.yml
|
114
|
+
- spec/fixtures/templates/Example/RegularFileWithContents.txt
|
115
|
+
- spec/fixtures/templates/Example/XXCLASS_PREFIXXXPrefixedFile.txt
|
116
|
+
- spec/fixtures/templates/Example/XXPROJECT_IDXX/BinaryFile.png
|
117
|
+
- spec/fixtures/templates/Example/XXPROJECT_IDXX/XXCLASS_PREFIXXXPrefixedFileInDirectory.txt
|
118
|
+
- spec/klipp/configuration_spec.rb
|
119
|
+
- spec/klipp/project_spec.rb
|
120
|
+
- spec/klipp/template_spec.rb
|
121
|
+
- spec/klipp/token_spec.rb
|
122
|
+
- spec/klipp_spec.rb
|
123
|
+
- spec/spec_helper.rb
|
124
|
+
homepage: https://github.com/epologee/klipp
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.0.2
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Klipp is a command line gem for creating new (Xcode) projects from existing
|
148
|
+
templates. Unlike Apple's private plist-based templating system, Klipp takes an
|
149
|
+
existing Xcode project and creates a new project by copying and modifying an existing
|
150
|
+
template project by your own specifications.
|
151
|
+
test_files:
|
152
|
+
- spec/fixtures/klipps/Example.klippfile
|
153
|
+
- spec/fixtures/klipps/ExcessiveExample.klippfile
|
154
|
+
- spec/fixtures/klipps/Generated.klippfile
|
155
|
+
- spec/fixtures/klipps/LackingExample.klippfile
|
156
|
+
- spec/fixtures/klipps/MalformedExample.klippfile
|
157
|
+
- spec/fixtures/klipps/single-token.yml
|
158
|
+
- spec/fixtures/templates/Example.yml
|
159
|
+
- spec/fixtures/templates/Example/RegularFileWithContents.txt
|
160
|
+
- spec/fixtures/templates/Example/XXCLASS_PREFIXXXPrefixedFile.txt
|
161
|
+
- spec/fixtures/templates/Example/XXPROJECT_IDXX/BinaryFile.png
|
162
|
+
- spec/fixtures/templates/Example/XXPROJECT_IDXX/XXCLASS_PREFIXXXPrefixedFileInDirectory.txt
|
163
|
+
- spec/klipp/configuration_spec.rb
|
164
|
+
- spec/klipp/project_spec.rb
|
165
|
+
- spec/klipp/template_spec.rb
|
166
|
+
- spec/klipp/token_spec.rb
|
167
|
+
- spec/klipp_spec.rb
|
168
|
+
- spec/spec_helper.rb
|