linecook 0.6.2

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.
Files changed (47) hide show
  1. data/History +60 -0
  2. data/License.txt +22 -0
  3. data/README +98 -0
  4. data/bin/linecook +58 -0
  5. data/cookbook +0 -0
  6. data/lib/linecook/attributes.rb +22 -0
  7. data/lib/linecook/commands/command.rb +48 -0
  8. data/lib/linecook/commands/command_error.rb +6 -0
  9. data/lib/linecook/commands/env.rb +23 -0
  10. data/lib/linecook/commands/helper.rb +51 -0
  11. data/lib/linecook/commands/helpers.rb +28 -0
  12. data/lib/linecook/commands/init.rb +82 -0
  13. data/lib/linecook/commands/package.rb +39 -0
  14. data/lib/linecook/commands/vbox.rb +85 -0
  15. data/lib/linecook/commands.rb +6 -0
  16. data/lib/linecook/cookbook.rb +104 -0
  17. data/lib/linecook/helper.rb +117 -0
  18. data/lib/linecook/package.rb +197 -0
  19. data/lib/linecook/recipe.rb +103 -0
  20. data/lib/linecook/shell/posix.rb +145 -0
  21. data/lib/linecook/shell/test.rb +254 -0
  22. data/lib/linecook/shell/unix.rb +117 -0
  23. data/lib/linecook/shell/utils.rb +138 -0
  24. data/lib/linecook/shell.rb +11 -0
  25. data/lib/linecook/template.rb +111 -0
  26. data/lib/linecook/test/file_test.rb +77 -0
  27. data/lib/linecook/test/regexp_escape.rb +86 -0
  28. data/lib/linecook/test.rb +172 -0
  29. data/lib/linecook/utils.rb +53 -0
  30. data/lib/linecook/version.rb +8 -0
  31. data/lib/linecook.rb +6 -0
  32. data/templates/Gemfile +2 -0
  33. data/templates/README +90 -0
  34. data/templates/Rakefile +149 -0
  35. data/templates/_gitignore +5 -0
  36. data/templates/attributes/project_name.rb +4 -0
  37. data/templates/cookbook +9 -0
  38. data/templates/files/file.txt +1 -0
  39. data/templates/helpers/project_name/echo.erb +5 -0
  40. data/templates/project_name.gemspec +30 -0
  41. data/templates/recipes/project_name.rb +20 -0
  42. data/templates/scripts/project_name.yml +7 -0
  43. data/templates/templates/template.txt.erb +3 -0
  44. data/templates/vbox/setup/virtual_box +86 -0
  45. data/templates/vbox/ssh/id_rsa +27 -0
  46. data/templates/vbox/ssh/id_rsa.pub +1 -0
  47. metadata +166 -0
@@ -0,0 +1,86 @@
1
+ module Linecook
2
+ module Test
3
+ # RegexpEscape is a subclass of regexp that escapes all but the text in a
4
+ # special escape sequence. This allows the creation of complex regexps
5
+ # to match, for instance, console output.
6
+ #
7
+ # The RegexpEscape.escape (or equivalently the quote) method does the
8
+ # work; all regexp-active characters are escaped except for characters
9
+ # enclosed by ':.' and '.:' delimiters.
10
+ #
11
+ # RegexpEscape.escape('reg[exp]+ chars. are(quoted)') # => 'reg\[exp\]\+\ chars\.\ are\(quoted\)'
12
+ # RegexpEscape.escape('these are not: :.a(b*)c.:') # => 'these\ are\ not:\ a(b*)c'
13
+ #
14
+ # In addition, all-period regexps are automatically upgraded to '.*?';
15
+ # use the '.{n}' notation to specify n arbitrary characters.
16
+ #
17
+ # RegexpEscape.escape('_:..:_:...:_:....:') # => '_.*?_.*?_.*?'
18
+ # RegexpEscape.escape(':..{1}.:') # => '.{1}'
19
+ #
20
+ # RegexpEscape instances are initialized using the escaped input string
21
+ # and return the original string upon to_s.
22
+ #
23
+ # str = %q{
24
+ # a multiline
25
+ # :...:
26
+ # example}
27
+ # r = RegexpEscape.new(str)
28
+ #
29
+ # r =~ %q{
30
+ # a multiline
31
+ # matching
32
+ # example} # => true
33
+ #
34
+ # r !~ %q{
35
+ # a failing multiline
36
+ # example} # => true
37
+ #
38
+ # r.to_s # => str
39
+ #
40
+ class RegexpEscape < Regexp
41
+
42
+ # matches the escape sequence
43
+ ESCAPE_SEQUENCE = /:\..*?\.:/
44
+
45
+ class << self
46
+
47
+ # Escapes regexp-active characters in str, except for character
48
+ # delimited by ':.' and '.:'. See the class description for
49
+ # details.
50
+ def escape(str)
51
+ substituents = []
52
+ str.scan(ESCAPE_SEQUENCE) do
53
+ regexp_str = $&[2...-2]
54
+ regexp_str = ".*?" if regexp_str =~ /^\.*$/
55
+ substituents << regexp_str
56
+ end
57
+ substituents << ""
58
+
59
+ splits = str.split(ESCAPE_SEQUENCE).collect do |split|
60
+ super(split)
61
+ end
62
+ splits << "" if splits.empty?
63
+
64
+ splits.zip(substituents).to_a.flatten.join
65
+ end
66
+
67
+ # Same as escape.
68
+ def quote(str)
69
+ escape(str)
70
+ end
71
+ end
72
+
73
+ # Generates a new RegexpEscape by escaping the str, using the same
74
+ # options as Regexp.
75
+ def initialize(str, *options)
76
+ super(RegexpEscape.escape(str), *options)
77
+ @original_str = str
78
+ end
79
+
80
+ # Returns the original string for self
81
+ def to_s
82
+ @original_str
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,172 @@
1
+ require 'linecook/cookbook'
2
+ require 'linecook/recipe'
3
+ require 'linecook/test/file_test'
4
+ require 'linecook/test/regexp_escape'
5
+ require 'linecook/utils'
6
+
7
+ module Linecook
8
+ module Test
9
+ include FileTest
10
+
11
+ attr_writer :cookbook
12
+ attr_writer :script
13
+ attr_writer :recipe
14
+
15
+ def cookbook
16
+ @cookbook ||= Cookbook.init(user_dir)
17
+ end
18
+
19
+ def manifest
20
+ cookbook.manifest
21
+ end
22
+
23
+ def default_env
24
+ {Package::CONFIG_KEY => {Package::MANIFEST_KEY => manifest}}
25
+ end
26
+
27
+ def recipe
28
+ @recipe ||= Recipe.new('recipe', default_env)
29
+ end
30
+
31
+ def build(env={})
32
+ env = Utils.deep_merge(default_env, env)
33
+ Recipe.build(env).export File.join(method_dir, 'scripts')
34
+ end
35
+
36
+ # Asserts whether or not the a and b strings are equal, with a more
37
+ # readable output than assert_equal for large strings (especially large
38
+ # strings with significant whitespace).
39
+ #
40
+ # One gotcha is that assert_output_equal lstrips indentation off of 'a',
41
+ # so that these all pass:
42
+ #
43
+ # assert_output_equal %q{
44
+ # line one
45
+ # line two
46
+ # }, "line one\nline two\n"
47
+ #
48
+ # assert_output_equal %q{
49
+ # line one
50
+ # line two
51
+ # }, "line one\nline two\n
52
+ #
53
+ # assert_output_equal %q{
54
+ # line one
55
+ # line two
56
+ # }, "line one\nline two\n"
57
+ #
58
+ # Use the assert_output_equal! method to prevent indentation stripping.
59
+ def assert_output_equal(a, b, msg=nil)
60
+ a = strip_indent(a)
61
+ assert_output_equal!(a, b, msg)
62
+ end
63
+
64
+ # Same as assert_output_equal but without indentation stripping.
65
+ def assert_output_equal!(a, b, msg=nil)
66
+ if a == b
67
+ assert true
68
+ else
69
+ flunk %Q{
70
+ #{msg}
71
+ ==================== expected output ====================
72
+ #{whitespace_escape(a)}
73
+ ======================== but was ========================
74
+ #{whitespace_escape(b)}
75
+ =========================================================
76
+ }
77
+ end
78
+ end
79
+
80
+ # Asserts whether or not b is like a (which should be a Regexp), and
81
+ # provides a more readable output in the case of a failure as compared
82
+ # with assert_match.
83
+ #
84
+ # If a is a string, then indentation is stripped off and it is turned
85
+ # into a RegexpEscape. Using that syntax, all these pass:
86
+ #
87
+ # assert_alike %q{
88
+ # the time is: :...:
89
+ # now!
90
+ # }, "the time is: #{Time.now}\nnow!\n"
91
+ #
92
+ # assert_alike %q{
93
+ # the time is: :...:
94
+ # now!
95
+ # }, "the time is: #{Time.now}\nnow!\n"
96
+ #
97
+ # assert_alike %q{
98
+ # the time is: :...:
99
+ # now!
100
+ # }, "the time is: #{Time.now}\nnow!\n"
101
+ #
102
+ # Use assert_alike! to prevent indentation stripping (conversion to a
103
+ # RegexpEscape is still in effect).
104
+ def assert_alike(a, b, msg=nil)
105
+ a = strip_indent(a) if a.kind_of?(String)
106
+ assert_alike!(a, b, msg)
107
+ end
108
+
109
+ # Same as assert_alike but without indentation stripping.
110
+ def assert_alike!(a, b, msg=nil)
111
+ a = RegexpEscape.new(a) if a.kind_of?(String)
112
+
113
+ if b =~ a
114
+ assert true
115
+ else
116
+ flunk %Q{
117
+ #{msg}
118
+ ================= expected output like ==================
119
+ #{whitespace_escape(a)}
120
+ ======================== but was ========================
121
+ #{whitespace_escape(b)}
122
+ =========================================================
123
+ }
124
+ end
125
+ end
126
+
127
+ def assert_recipe(expected, &block)
128
+ recipe.instance_eval(&block)
129
+ assert_output_equal expected, recipe.result
130
+ end
131
+
132
+ def assert_recipe_match(expected, &block)
133
+ recipe.instance_eval(&block)
134
+ assert_alike expected, recipe.result
135
+ end
136
+
137
+ def assert_content(expected, build_path)
138
+ registry = recipe.close
139
+
140
+ assert_equal true, registry.has_key?(build_path), "not in registry: #{build_path}"
141
+ assert_output_equal expected, File.read(registry[build_path]), build_path
142
+ end
143
+
144
+ private
145
+
146
+ # helper for stripping indentation off a string
147
+ def strip_indent(str) # :nodoc:
148
+ if str =~ /\A\s*?\n( *)(.*)\z/m
149
+ indent, str = $1, $2, $3
150
+
151
+ if indent.length > 0
152
+ str.gsub!(/^ {0,#{indent.length}}/, '')
153
+ end
154
+ end
155
+
156
+ str
157
+ end
158
+
159
+ # helper for formatting escaping whitespace into readable text
160
+ def whitespace_escape(str) # :nodoc:
161
+ str.to_s.gsub(/\s/) do |match|
162
+ case match
163
+ when "\n" then "\\n\n"
164
+ when "\t" then "\\t"
165
+ when "\r" then "\\r"
166
+ when "\f" then "\\f"
167
+ else match
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,53 @@
1
+ module Linecook
2
+ module Utils
3
+ module_function
4
+
5
+ def nest_hash
6
+ Hash.new {|hash, key| hash[key] = nest_hash }
7
+ end
8
+
9
+ def serial_merge(*hashes)
10
+ attrs = {}
11
+ while overrides = hashes.shift
12
+ attrs = deep_merge(attrs, overrides)
13
+ end
14
+ attrs
15
+ end
16
+
17
+ def deep_merge(a, b)
18
+ b.each_pair do |key, current|
19
+ previous = a[key]
20
+ a[key] = deep_merge?(previous, current) ? deep_merge(previous, current) : current
21
+ end
22
+
23
+ a
24
+ end
25
+
26
+ def deep_merge?(previous, current)
27
+ current.kind_of?(Hash) && previous.kind_of?(Hash)
28
+ end
29
+
30
+ def camelize(str)
31
+ str.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
32
+ end
33
+
34
+ def underscore(str)
35
+ str.gsub(/::/, '/').
36
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
37
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
38
+ tr("-", "_").
39
+ downcase
40
+ end
41
+
42
+ def constantize(const_name)
43
+ constants = camelize(const_name).split(/::/)
44
+
45
+ const = Object
46
+ while name = constants.shift
47
+ const = const.const_get(name)
48
+ end
49
+
50
+ const
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,8 @@
1
+ module Linecook
2
+ MAJOR = 0
3
+ MINOR = 6
4
+ TINY = 2
5
+
6
+ VERSION = "#{MAJOR}.#{MINOR}.#{TINY}"
7
+ WEBSITE = "http://github.com/pinnacol/linecook"
8
+ end
data/lib/linecook.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'linecook/helper'
2
+ require 'linecook/script'
3
+ require 'linecook/cookbook'
4
+
5
+ module Linecook
6
+ end
data/templates/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/templates/README ADDED
@@ -0,0 +1,90 @@
1
+ = README
2
+
3
+ Linecook provides support to develop scripts using VirtualBox, an open-source
4
+ product to setup and manage virtual machines. Nothing says you have to use
5
+ VirtualBox during development and obviously you can take the shell scripts
6
+ produced by Linecook and run them wherever.
7
+
8
+ These are instructions for setting up a generic Ubuntu VM for development.
9
+
10
+ 1. Download and Install VirtualBox (http://www.virtualbox.org)
11
+ 2. Download a Ubuntu ISO (http://www.ubuntu.com/server/get-ubuntu/download)
12
+ 3. Build the Box
13
+
14
+ Use the VirtualBox wizard to get started.
15
+
16
+ - name: vbox
17
+ - Linux/Ubuntu
18
+ - 512 MB memory
19
+ - 8 GB dynamically resizing drive
20
+
21
+ Under Settings:
22
+
23
+ - add the ubuntu iso to the cd/dvd device (under storage)
24
+ - disable audio
25
+ - network set to NAT
26
+ - disable usb (only the inner box would stay unchecked)
27
+ - shared folder: map the 'vbox' directory in project root
28
+
29
+ Start the server and install (default unless specified):
30
+
31
+ - hostname: vbox-ubuntu
32
+ - user/password: vbox
33
+ - no packages
34
+ - power off, remove ubuntu iso from the cd/dvd device
35
+
36
+ Setup Permissions (allows vbox to run sudo without password):
37
+
38
+ vm: sudo visudo
39
+
40
+ # insert line:
41
+ #
42
+ # %vbox ALL=NOPASSWD: ALL
43
+ #
44
+ # then exit (write out changes as prompted)
45
+
46
+ Setup guest additions (note they are in the application package on
47
+ osx http://forums.virtualbox.org/viewtopic.php?f=8&t=10286) See also:
48
+ http://forums.virtualbox.org/viewtopic.php?t=15868.
49
+
50
+ (cd/dvd device): add the VBoxGuestAdditions.iso
51
+ vm: sudo apt-get install linux-headers-$(uname -r) build-essential ssh openssh-server
52
+ vm: sudo mkdir /media/dvd
53
+ vm: sudo mount /dev/dvd /media/dvd/
54
+ vm: sudo sh /media/dvd/VBoxLinuxAdditions-x86.run
55
+ # there may be a warning about 'Window System drivers fail', ignore
56
+
57
+ Add an init script to mount the share on boot:
58
+
59
+ vm: sudo mkdir /vbox
60
+ vm: sudo mount -t vboxsf -o uid=1000,gid=100 vbox /vbox
61
+ vm: sudo cp /vbox/setup/virtual_box /etc/init.d
62
+ vm: sudo chmod 0755 /etc/init.d/virtual_box
63
+ vm: sudo update-rc.d virtual_box defaults 80
64
+
65
+ Setup SSH:
66
+
67
+ vm: mkdir ~/.ssh
68
+ vm: chmod 0700 ~/.ssh
69
+ vm: cat /vbox/ssh/id_rsa.pub >> ~/.ssh/authorized_keys
70
+ vm: chmod 0600 ~/.ssh/authorized_keys
71
+
72
+ Now take a snapshot and setup port forwarding:
73
+
74
+ vm: exit
75
+ ht: VBoxManage snapshot vbox take BASE
76
+ ht: VBoxManage controlvm vbox poweroff
77
+ ht: VBoxManage modifyvm vbox --natpf1 'guestssh,tcp,,2222,,22'
78
+ ht: VBoxManage modifyvm vbox --natpf1 'http,tcp,,8888,,80'
79
+ ht: VBoxManage -q snapshot vbox restore BASE
80
+ ht: VBoxManage startvm vbox --type headless
81
+
82
+ You can now ssh to the box (from the project dir):
83
+
84
+ ht: chmod 0600 vbox/ssh/id_rsa
85
+ ht: ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o IdentitiesOnly=yes -i vbox/ssh/id_rsa vbox@localhost
86
+
87
+ To cleanup the port forwarding (run later):
88
+
89
+ ht: VBoxManage modifyvm vbox --natpf1 delete 'guestssh'
90
+ ht: VBoxManage modifyvm vbox --natpf1 delete 'http'
@@ -0,0 +1,149 @@
1
+ require 'rake'
2
+
3
+ #
4
+ # Gem tasks
5
+ #
6
+
7
+ require 'rake/rdoctask'
8
+ require 'rake/gempackagetask'
9
+
10
+ def gemspec
11
+ @gemspec ||= eval(File.read('<%= project_name %>.gemspec'), TOPLEVEL_BINDING)
12
+ end
13
+
14
+ Rake::GemPackageTask.new(gemspec) do |pkg|
15
+ pkg.need_tar = true
16
+ end
17
+
18
+ desc 'Prints the gemspec manifest.'
19
+ task :print_manifest do
20
+ files = gemspec.files.inject({}) do |files, file|
21
+ files[File.expand_path(file)] = [File.exists?(file), file]
22
+ files
23
+ end
24
+
25
+ cookbook_files = Dir.glob('{attributes,files,lib,recipes,templates}/**/*')
26
+ cookbook_file = Dir.glob('*')
27
+
28
+ (cookbook_files + cookbook_file).each do |file|
29
+ next unless File.file?(file)
30
+ path = File.expand_path(file)
31
+ files[path] = ['', file] unless files.has_key?(path)
32
+ end
33
+
34
+ # sort and output the results
35
+ files.values.sort_by {|exists, file| file }.each do |entry|
36
+ puts '%-5s %s' % entry
37
+ end
38
+ end
39
+
40
+ #
41
+ # Documentation tasks
42
+ #
43
+
44
+ desc 'Generate documentation.'
45
+ Rake::RDocTask.new(:rdoc) do |rdoc|
46
+ spec = gemspec
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.options.concat(spec.rdoc_options)
50
+ rdoc.rdoc_files.include(spec.extra_rdoc_files)
51
+
52
+ files = spec.files.select {|file| file =~ /^lib.*\.rb$/}
53
+ rdoc.rdoc_files.include( files )
54
+ end
55
+
56
+ #
57
+ # Dependency tasks
58
+ #
59
+
60
+ desc 'Bundle dependencies'
61
+ task :bundle do
62
+ output = `bundle check 2>&1`
63
+
64
+ unless $?.to_i == 0
65
+ puts output
66
+ sh "bundle install 2>&1"
67
+ puts
68
+ end
69
+ end
70
+
71
+ #
72
+ # Linecook Helpers
73
+ #
74
+
75
+ lib_dir = File.expand_path("../lib", __FILE__)
76
+ helpers_dir = File.expand_path("../helpers", __FILE__)
77
+
78
+ sources = {}
79
+ helpers = []
80
+
81
+ Dir.glob("#{helpers_dir}/**/*").each do |source|
82
+ next if File.directory?(source)
83
+ (sources[File.dirname(source)] ||= []) << source
84
+ end
85
+
86
+ sources.each_pair do |dir, sources|
87
+ name = dir[(helpers_dir.length + 1)..-1]
88
+ target = File.join(lib_dir, 'linebook', "#{name}.rb")
89
+
90
+ file target => sources + [dir] do
91
+ system "bundle exec linecook helper '#{name}' --force"
92
+ end
93
+
94
+ helpers << target
95
+ end
96
+
97
+ desc "generate helpers"
98
+ task :helpers => helpers + [:bundle]
99
+
100
+ #
101
+ # Linecook Scripts
102
+ #
103
+
104
+ scripts = Dir.glob("scripts/*.yml")
105
+ dependencies = Dir.glob('{attributes,files,recipes,templates}/**/*')
106
+
107
+ scripts.each do |source|
108
+ target = source.chomp('.yml')
109
+ name = File.basename(target)
110
+
111
+ namespace :scripts do
112
+ file target => dependencies + [source] + helpers do
113
+ sh "bundle exec linecook package '#{source}' '#{target}' --force"
114
+ end
115
+
116
+ desc "generate the script: #{name}"
117
+ task name => target
118
+ end
119
+
120
+ task :scripts => target
121
+ end
122
+
123
+ desc "generate scripts"
124
+ task :scripts
125
+
126
+ #
127
+ # Test tasks
128
+ #
129
+
130
+ desc 'Default: Run tests.'
131
+ task :default => :test
132
+
133
+ desc 'Run the tests'
134
+ task :test => :helpers do
135
+ tests = Dir.glob('test/**/*_test.rb')
136
+
137
+ if ENV['RCOV'] == 'true'
138
+ FileUtils.rm_rf File.expand_path('../coverage', __FILE__)
139
+ sh('rcov', '-w', '--text-report', '--exclude', '^/', *tests)
140
+ else
141
+ sh('ruby', '-w', '-e', 'ARGV.dup.each {|test| load test}', *tests)
142
+ end
143
+ end
144
+
145
+ desc 'Run rcov'
146
+ task :rcov do
147
+ ENV['RCOV'] = 'true'
148
+ Rake::Task["test"].invoke
149
+ end
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ .bundle
3
+ *.gem
4
+ /rdoc
5
+ vbox/log
@@ -0,0 +1,4 @@
1
+ # Define default recipe attributes here and include in a recipe using
2
+ # 'attributes "filename"'. Script attributes override these values.
3
+ attrs['<%= project_name %>']['letters'] = ['a', 'b', 'c']
4
+ attrs['<%= project_name %>']['numbers'] = [1, 2, 3]
@@ -0,0 +1,9 @@
1
+ # Configure the cookbook here.
2
+ # Adding this file to a gem marks it as a cookbook gem
3
+ # (note that in a gem the contents of this file are ignored)
4
+
5
+ # Define directories searched for attributes/recipes/etc.
6
+ # paths: ['.']
7
+
8
+ # Name the gems added to path - defaults to all marked gems.
9
+ # gems: []
@@ -0,0 +1 @@
1
+ Contents of an example file.
@@ -0,0 +1,5 @@
1
+ An example of a helper definition. This is the documentation, followed by the
2
+ method signature and then the ERB template.
3
+ (*args)
4
+ --
5
+ echo '<%= "<" + "%= args.join(' ') %"+ ">" %>'
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "<%= project_name %>"
5
+ s.version = "0.0.1"
6
+ s.platform = Gem::Platform::RUBY
7
+ s.authors = "TODO: Write your name"
8
+ s.email = "TODO: Write your email address"
9
+ s.homepage = ""
10
+ s.summary = %q{TODO: Write a gem summary}
11
+ s.description = %q{TODO: Write a gem description}
12
+ s.rubyforge_project = ''
13
+
14
+ s.has_rdoc = true
15
+ s.rdoc_options.concat %W{--main README -S -N --title <%= project_name.capitalize %>}
16
+
17
+ # add dependencies
18
+ s.add_dependency('linecook', '~> <%= Linecook::VERSION %>')
19
+
20
+ # list extra rdoc files here.
21
+ s.extra_rdoc_files = %W{
22
+ cookbook
23
+ }
24
+
25
+ # list the files you want to include here.
26
+ s.files = %W{
27
+ }
28
+
29
+ s.require_path = 'lib'
30
+ end
@@ -0,0 +1,20 @@
1
+ #############################################################################
2
+ helpers 'linecook/shell'
3
+ helpers 'linebook/<%= project_name %>'
4
+ attributes '<%= project_name %>'
5
+ #############################################################################
6
+
7
+ shebang '/bin/bash'
8
+
9
+ # Write to the script target using 'script'
10
+ target.puts '# An example script.'
11
+
12
+ # Helpers are now available, as are attributes.
13
+ echo *attrs['<%= project_name %>']['letters']
14
+ echo *attrs['<%= project_name %>']['numbers']
15
+
16
+ # Use files like this:
17
+ cat file_path('file.txt')
18
+
19
+ # Use templates like this:
20
+ cat template_path('template.txt', :n => 10)
@@ -0,0 +1,7 @@
1
+ # Configure Linecook
2
+ linecook:
3
+ recipes: [<%= project_name %>]
4
+
5
+ # Set attributes for the script
6
+ <%= project_name %>:
7
+ numbers: [7, 8, 9]
@@ -0,0 +1,3 @@
1
+ <%= '<' %>% n.times do %<%= '>' %>
2
+ Contents of a template file.
3
+ <%= '<' %>% end %<%= '>' %>