rubycut-babushka 0.10.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. data/Gemfile +8 -0
  2. data/Gemfile.lock +31 -0
  3. data/README.markdown +246 -0
  4. data/Rakefile +26 -0
  5. data/bin/babushka +11 -0
  6. data/deps/babushka.rb +101 -0
  7. data/deps/dev.rb +12 -0
  8. data/deps/fhs.rb +31 -0
  9. data/deps/git.rb +29 -0
  10. data/deps/homebrew.rb +30 -0
  11. data/deps/os_x.rb +33 -0
  12. data/deps/packages.rb +22 -0
  13. data/deps/pkg_managers.rb +110 -0
  14. data/deps/ruby.rb +23 -0
  15. data/deps/rubygems.rb +24 -0
  16. data/deps/system.rb +10 -0
  17. data/deps/templates/app.rb +68 -0
  18. data/deps/templates/external.rb +12 -0
  19. data/deps/templates/installer.rb +31 -0
  20. data/deps/templates/managed.rb +105 -0
  21. data/deps/templates/ppa.rb +24 -0
  22. data/deps/templates/src.rb +42 -0
  23. data/deps/templates/tmbundle.rb +15 -0
  24. data/lib/babushka.rb +28 -0
  25. data/lib/babushka/accepts_block_for.rb +72 -0
  26. data/lib/babushka/accepts_list_for.rb +49 -0
  27. data/lib/babushka/accepts_value_for.rb +24 -0
  28. data/lib/babushka/base.rb +78 -0
  29. data/lib/babushka/bug_reporter.rb +55 -0
  30. data/lib/babushka/cmdline.rb +133 -0
  31. data/lib/babushka/cmdline/handler.rb +41 -0
  32. data/lib/babushka/cmdline/helpers.rb +127 -0
  33. data/lib/babushka/cmdline/parser.rb +69 -0
  34. data/lib/babushka/colorizer.rb +59 -0
  35. data/lib/babushka/core_patches/array.rb +171 -0
  36. data/lib/babushka/core_patches/blank.rb +22 -0
  37. data/lib/babushka/core_patches/bytes.rb +52 -0
  38. data/lib/babushka/core_patches/hash.rb +107 -0
  39. data/lib/babushka/core_patches/hashish.rb +14 -0
  40. data/lib/babushka/core_patches/integer.rb +25 -0
  41. data/lib/babushka/core_patches/io.rb +8 -0
  42. data/lib/babushka/core_patches/numeric.rb +16 -0
  43. data/lib/babushka/core_patches/object.rb +27 -0
  44. data/lib/babushka/core_patches/string.rb +116 -0
  45. data/lib/babushka/core_patches/symbol.rb +12 -0
  46. data/lib/babushka/core_patches/try.rb +15 -0
  47. data/lib/babushka/core_patches/uri.rb +24 -0
  48. data/lib/babushka/dep.rb +470 -0
  49. data/lib/babushka/dep_context.rb +18 -0
  50. data/lib/babushka/dep_definer.rb +115 -0
  51. data/lib/babushka/dep_pool.rb +49 -0
  52. data/lib/babushka/dep_runner.rb +85 -0
  53. data/lib/babushka/dsl.rb +26 -0
  54. data/lib/babushka/git_repo.rb +185 -0
  55. data/lib/babushka/helpers/git_helpers.rb +32 -0
  56. data/lib/babushka/helpers/log_helpers.rb +176 -0
  57. data/lib/babushka/helpers/path_helpers.rb +34 -0
  58. data/lib/babushka/helpers/run_helpers.rb +145 -0
  59. data/lib/babushka/helpers/shell_helpers.rb +229 -0
  60. data/lib/babushka/helpers/suggest_helpers.rb +16 -0
  61. data/lib/babushka/helpers/uri_helpers.rb +36 -0
  62. data/lib/babushka/ip.rb +160 -0
  63. data/lib/babushka/lambda_chooser.rb +40 -0
  64. data/lib/babushka/levenshtein.rb +125 -0
  65. data/lib/babushka/meta_dep.rb +65 -0
  66. data/lib/babushka/meta_dep_context.rb +15 -0
  67. data/lib/babushka/parameter.rb +143 -0
  68. data/lib/babushka/pkg_helper.rb +81 -0
  69. data/lib/babushka/pkg_helpers/apt_helper.rb +61 -0
  70. data/lib/babushka/pkg_helpers/base_helper.rb +19 -0
  71. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +48 -0
  72. data/lib/babushka/pkg_helpers/binports_helper.rb +34 -0
  73. data/lib/babushka/pkg_helpers/brew_helper.rb +110 -0
  74. data/lib/babushka/pkg_helpers/gem_helper.rb +120 -0
  75. data/lib/babushka/pkg_helpers/macports_helper.rb +22 -0
  76. data/lib/babushka/pkg_helpers/npm_helper.rb +45 -0
  77. data/lib/babushka/pkg_helpers/pacman_helper.rb +27 -0
  78. data/lib/babushka/pkg_helpers/pip_helper.rb +45 -0
  79. data/lib/babushka/pkg_helpers/src_helper.rb +16 -0
  80. data/lib/babushka/pkg_helpers/yum_helper.rb +25 -0
  81. data/lib/babushka/popen.rb +40 -0
  82. data/lib/babushka/prompt.rb +176 -0
  83. data/lib/babushka/renderable.rb +67 -0
  84. data/lib/babushka/resource.rb +215 -0
  85. data/lib/babushka/run_reporter.rb +60 -0
  86. data/lib/babushka/shell.rb +108 -0
  87. data/lib/babushka/source.rb +216 -0
  88. data/lib/babushka/source_pool.rb +146 -0
  89. data/lib/babushka/system_definitions.rb +97 -0
  90. data/lib/babushka/system_profile.rb +210 -0
  91. data/lib/babushka/task.rb +142 -0
  92. data/lib/babushka/vars.rb +108 -0
  93. data/lib/babushka/version_of.rb +65 -0
  94. data/lib/babushka/version_str.rb +57 -0
  95. data/lib/babushka/xml_string.rb +28 -0
  96. data/lib/components.rb +82 -0
  97. data/lib/fancypath/fancypath.rb +200 -0
  98. data/lib/inkan/inkan.rb +76 -0
  99. data/spec/acceptance/acceptance.rb +43 -0
  100. data/spec/acceptance_helper.rb +113 -0
  101. data/spec/archives/Blah.app.zip +0 -0
  102. data/spec/archives/archive.tar +0 -0
  103. data/spec/archives/archive.tar.bz2 +0 -0
  104. data/spec/archives/archive.tar.gz +0 -0
  105. data/spec/archives/archive.tbz2 +0 -0
  106. data/spec/archives/archive.tgz +0 -0
  107. data/spec/archives/archive.zip +0 -0
  108. data/spec/archives/content.txt +5 -0
  109. data/spec/archives/invalid_archive +5 -0
  110. data/spec/archives/nested archive/content.txt +5 -0
  111. data/spec/archives/nested_archive.tar +0 -0
  112. data/spec/archives/really_a_gzip.zip +0 -0
  113. data/spec/archives/test-0.3.1.tgz +0 -0
  114. data/spec/archives/tgz_archive +0 -0
  115. data/spec/archives/zip_without_extension +0 -0
  116. data/spec/babushka/accepts_for_spec.rb +174 -0
  117. data/spec/babushka/accepts_for_support.rb +72 -0
  118. data/spec/babushka/cmdline/console_spec.rb +11 -0
  119. data/spec/babushka/cmdline/help_spec.rb +61 -0
  120. data/spec/babushka/cmdline/version_spec.rb +10 -0
  121. data/spec/babushka/core_patches_spec.rb +171 -0
  122. data/spec/babushka/dep_context_spec.rb +58 -0
  123. data/spec/babushka/dep_definer_spec.rb +152 -0
  124. data/spec/babushka/dep_definer_support.rb +36 -0
  125. data/spec/babushka/dep_spec.rb +567 -0
  126. data/spec/babushka/dep_support.rb +29 -0
  127. data/spec/babushka/deps_spec.rb +113 -0
  128. data/spec/babushka/gem_helper_spec.rb +90 -0
  129. data/spec/babushka/git_repo_spec.rb +396 -0
  130. data/spec/babushka/ip_spec.rb +131 -0
  131. data/spec/babushka/lambda_chooser_spec.rb +115 -0
  132. data/spec/babushka/meta_dep_definer_spec.rb +127 -0
  133. data/spec/babushka/meta_dep_wrapper_spec.rb +32 -0
  134. data/spec/babushka/parameter_spec.rb +135 -0
  135. data/spec/babushka/path_helpers_spec.rb +102 -0
  136. data/spec/babushka/prompt_spec.rb +188 -0
  137. data/spec/babushka/renderable_spec.rb +100 -0
  138. data/spec/babushka/resource_spec.rb +141 -0
  139. data/spec/babushka/run_helpers_spec.rb +26 -0
  140. data/spec/babushka/shell_helpers_spec.rb +244 -0
  141. data/spec/babushka/shell_spec.rb +19 -0
  142. data/spec/babushka/source_pool_spec.rb +320 -0
  143. data/spec/babushka/source_pool_support.rb +31 -0
  144. data/spec/babushka/source_spec.rb +382 -0
  145. data/spec/babushka/source_support.rb +17 -0
  146. data/spec/babushka/system_profile_spec.rb +61 -0
  147. data/spec/babushka/task_spec.rb +141 -0
  148. data/spec/babushka/uri_spec.rb +13 -0
  149. data/spec/babushka/vars_spec.rb +59 -0
  150. data/spec/babushka/version_of_spec.rb +110 -0
  151. data/spec/babushka/version_str_spec.rb +130 -0
  152. data/spec/babushka/version_str_support.rb +37 -0
  153. data/spec/babushka/xml_string_spec.rb +98 -0
  154. data/spec/deps/bad/broken.rb +7 -0
  155. data/spec/deps/bad/working.rb +3 -0
  156. data/spec/deps/good/meta.rb +14 -0
  157. data/spec/deps/good/test.rb +11 -0
  158. data/spec/deps/outer/deps.rb +19 -0
  159. data/spec/deps/outer/more deps.rb +11 -0
  160. data/spec/deps/params/params.rb +10 -0
  161. data/spec/fancypath/fancypath_spec.rb +272 -0
  162. data/spec/fancypath_support.rb +10 -0
  163. data/spec/inkan/inkan_spec.rb +217 -0
  164. data/spec/renderable/different_example.conf.erb +4 -0
  165. data/spec/renderable/example.conf.erb +3 -0
  166. data/spec/renderable/example.sh +6 -0
  167. data/spec/renderable/with_binding.conf.erb +4 -0
  168. data/spec/renderable/xml_example.conf.erb +8 -0
  169. data/spec/repos/remote.git.tgz +0 -0
  170. data/spec/spec_helper.rb +87 -0
  171. metadata +238 -0
@@ -0,0 +1,65 @@
1
+ module Babushka
2
+ class VersionOf
3
+ module Helpers
4
+ module_function
5
+
6
+ def VersionOf first, *rest
7
+ # Convert the arguments into a VersionOf. If a single string argument is
8
+ # passed, try splitting it on space to separate name and version. Otherwise,
9
+ # pass the arguments as-is, splatting if required.
10
+ if rest.any?
11
+ Babushka::VersionOf.new(*[first].concat(rest))
12
+ elsif first.is_a?(String)
13
+ Babushka::VersionOf.new(*first.split(' ', 2))
14
+ elsif first.is_a?(Array)
15
+ Babushka::VersionOf.new(*first)
16
+ else
17
+ Babushka::VersionOf.new(first)
18
+ end
19
+ end
20
+ end
21
+
22
+ attr_accessor :name, :version
23
+
24
+ def initialize name, version = nil
25
+ @name = name.respond_to?(:name) ? name.name : name
26
+ @version = if version.nil?
27
+ name.version if name.respond_to?(:version)
28
+ elsif version.is_a? VersionStr
29
+ version
30
+ else
31
+ version.to_version
32
+ end
33
+ end
34
+
35
+ def == other
36
+ if other.is_a? VersionOf
37
+ name == other.name &&
38
+ version == other.version
39
+ else
40
+ to_s == other.to_s
41
+ end
42
+ end
43
+
44
+ def <=> other
45
+ raise ArgumentError, "You can't compare the versions of two different things (#{name}, #{other.name})." unless name == other.name
46
+ version <=> other.version
47
+ end
48
+
49
+ def matches? other
50
+ if other.is_a? VersionStr
51
+ version.nil? || other.send(version.operator, version)
52
+ else
53
+ matches? other.to_version
54
+ end
55
+ end
56
+
57
+ def to_s joinery = '-'
58
+ [name, version].compact * joinery
59
+ end
60
+
61
+ def inspect
62
+ "#<VersionOf #{name}#{", v#{version}" unless version.nil?}>"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,57 @@
1
+ module Babushka
2
+ class VersionStrError < StandardError; end
3
+ class InvalidVersionOperator < VersionStrError; end
4
+ class InvalidVersionStr < VersionStrError; end
5
+
6
+ class VersionStr
7
+ include Comparable
8
+ attr_reader :pieces, :operator, :version
9
+ GemVersionOperators = %w[= == != > < >= <= ~>].freeze
10
+
11
+ def <=> other
12
+ other = other.to_version unless other.is_a? VersionStr
13
+ max_length = [pieces.length, other.pieces.length].max
14
+ (0...max_length).to_a.pick {|index|
15
+ result = compare_pieces pieces[index], other.pieces[index]
16
+ result unless result == 0
17
+ } || 0
18
+ end
19
+
20
+ def initialize str
21
+ @operator, @version = str.strip.scan(/^([^\s\w\-\.]+)?\s*v?([\w\-\.]+)$/i).first
22
+
23
+ if !(@operator.nil? || GemVersionOperators.include?(@operator))
24
+ raise InvalidVersionOperator, "VersionStr.new('#{str}'): invalid operator '#{@operator}'."
25
+ elsif @version.nil?
26
+ raise InvalidVersionStr, "VersionStr.new('#{str}'): couldn't parse a version number."
27
+ else
28
+ @pieces = @version.strip.scan(/\d+|[a-zA-Z]+|\w+/).map {|piece|
29
+ piece[/^\d+$/] ? piece.to_i : piece
30
+ }
31
+ @operator = '==' if @operator.nil? || @operator == '='
32
+ end
33
+ end
34
+
35
+ def to_s
36
+ @operator == '==' ? @version : "#{@operator} #{@version}"
37
+ end
38
+
39
+ define_method "!=" do |other|
40
+ !(self == other)
41
+ end
42
+
43
+ define_method "~>" do |other|
44
+ (self >= other) && pieces.starts_with?(other.pieces[0..-2])
45
+ end
46
+
47
+ private
48
+
49
+ def compare_pieces this, that
50
+ if this.is_a?(String) ^ that.is_a?(String)
51
+ this.is_a?(String) ? -1 : 1
52
+ else
53
+ (this || 0) <=> (that || 0)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,28 @@
1
+ module Babushka
2
+ class XMLString < String
3
+ # This extracts values from XML, like that found in .plist files. For example,
4
+ #
5
+ # %Q{
6
+ # <key>SVNPath</key>
7
+ # <string>/trunk/src</string>
8
+ # <key>SVNRevision</key>
9
+ # <string>37609</string>
10
+ # }.val_for('SVNRevision') #=> "37609"
11
+ #
12
+ # It doesn't work for arrays, and probably doesn't work for boolean values.
13
+ # Patches welcome :)
14
+ def val_for key
15
+ split(/<\/[^>]+>\n\s*<key>/m).select {|i|
16
+ i[/#{Regexp.escape(key)}<\/key>/]
17
+ }.map {|i|
18
+ i.scan(/<[^\/>]+>(.*)$/m)
19
+ }.flatten.first
20
+ end
21
+ end
22
+ end
23
+
24
+ class String
25
+ def xml_val_for key
26
+ Babushka::XMLString.new(self).val_for(key)
27
+ end
28
+ end
data/lib/components.rb ADDED
@@ -0,0 +1,82 @@
1
+ require 'singleton'
2
+
3
+ module Babushka
4
+ ExternalComponents = %w[
5
+ fancypath/fancypath
6
+ inkan/inkan
7
+ ]
8
+
9
+ Components = %w[
10
+ core_patches/blank
11
+ core_patches/try
12
+ core_patches/array
13
+ core_patches/hash
14
+ core_patches/hashish
15
+ core_patches/integer
16
+ core_patches/io
17
+ core_patches/numeric
18
+ core_patches/bytes
19
+ core_patches/object
20
+ core_patches/string
21
+ core_patches/symbol
22
+ core_patches/uri
23
+ xml_string
24
+ helpers/log_helpers
25
+ helpers/shell_helpers
26
+ helpers/path_helpers
27
+ helpers/run_helpers
28
+ helpers/suggest_helpers
29
+ helpers/git_helpers
30
+ helpers/uri_helpers
31
+ popen
32
+ shell
33
+ git_repo
34
+ resource
35
+ prompt
36
+ lambda_chooser
37
+ ip
38
+ version_str
39
+ version_of
40
+ accepts_list_for
41
+ accepts_value_for
42
+ accepts_block_for
43
+ colorizer
44
+ levenshtein
45
+ cmdline/parser
46
+ cmdline/handler
47
+ cmdline/helpers
48
+ cmdline
49
+ base
50
+ renderable
51
+ system_definitions
52
+ system_profile
53
+ run_reporter
54
+ bug_reporter
55
+ pkg_helper
56
+ pkg_helpers/base_helper
57
+ pkg_helpers/apt_helper
58
+ pkg_helpers/yum_helper
59
+ pkg_helpers/brew_helper
60
+ pkg_helpers/gem_helper
61
+ pkg_helpers/macports_helper
62
+ pkg_helpers/src_helper
63
+ pkg_helpers/pip_helper
64
+ pkg_helpers/binpkgsrc_helper
65
+ pkg_helpers/binports_helper
66
+ pkg_helpers/npm_helper
67
+ pkg_helpers/pacman_helper
68
+ dsl
69
+ dep
70
+ dep_pool
71
+ task
72
+ source
73
+ source_pool
74
+ vars
75
+ parameter
76
+ dep_runner
77
+ dep_definer
78
+ dep_context
79
+ meta_dep
80
+ meta_dep_context
81
+ ]
82
+ end
@@ -0,0 +1,200 @@
1
+ require 'pathname'
2
+
3
+ class Fancypath < Pathname
4
+ module Helpers
5
+ require 'etc'
6
+ def to_fancypath
7
+ Fancypath.new to_tilde_expanded_path
8
+ end
9
+ def to_expanded_fancypath
10
+ Fancypath.new File.expand_path(to_tilde_expanded_path)
11
+ end
12
+ def to_tilde_expanded_path
13
+ sub(/^\~\/|^\~$/) {|_| Etc.getpwuid(Process.euid).dir.end_with('/') }
14
+ end
15
+ alias :p :to_expanded_fancypath
16
+ end
17
+
18
+ # methods are chainable and do what you think they do
19
+
20
+ alias_method :to_str, :to_s unless method_defined? :to_str
21
+
22
+ alias_method :dir, :dirname
23
+ alias_method :directory, :dirname
24
+
25
+ alias_method :dir?, :directory?
26
+
27
+ alias_method :expand, :expand_path
28
+ alias_method :abs, :expand_path
29
+ alias_method :absolute, :expand_path
30
+
31
+ alias_method :exists?, :exist?
32
+ alias_method :rename_to, :rename
33
+
34
+ def == other
35
+ if other.is_a? String
36
+ to_s == other
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def length
43
+ to_s.length
44
+ end
45
+
46
+ def join(path)
47
+ path_str = path.to_s
48
+ super(path_str[0..0] == '/' ? path_str[1..-1] : path_str).p
49
+ end
50
+
51
+ alias_method :/, :join
52
+
53
+ # This method returns true if the path is writable (i.e. and already
54
+ # exists), or if the current user would be able to create it (i.e. if
55
+ # its closest existing parent is writable).
56
+ def hypothetically_writable?
57
+ writable? || (!exists? && !root? && parent.hypothetically_writable?)
58
+ end
59
+
60
+ # make file
61
+ def touch
62
+ `touch '#{self}'`
63
+ self
64
+ end
65
+
66
+ def create_dir
67
+ mkpath unless exist?
68
+ self
69
+ end
70
+
71
+ alias_method :create, :create_dir
72
+
73
+ def copy(dest)
74
+ `cp -pPR '#{self}' '#{dest}'`
75
+ self
76
+ end
77
+
78
+ alias_method :cp, :copy
79
+
80
+ # file or dir
81
+ def remove
82
+ directory? ? rmtree : delete if exist?
83
+ self
84
+ end
85
+ alias_method :rm, :remove
86
+
87
+ def read
88
+ super.chomp if exists?
89
+ end
90
+
91
+ def readlink
92
+ if !symlink?
93
+ self
94
+ elsif
95
+ target = super
96
+ target.absolute? ? target : (dir / target)
97
+ end
98
+ end
99
+
100
+ def mkdir
101
+ `mkdir -p '#{self}'`
102
+ self
103
+ end
104
+
105
+ def glob expr = nil, flags = File::FNM_CASEFOLD, &block
106
+ Dir.glob((expr.nil? ? self : (self / expr)).to_s, flags, &block)
107
+ end
108
+
109
+ def write(contents, mode='wb')
110
+ dirname.create
111
+ open(mode) { |f| f.write contents }
112
+ self
113
+ end
114
+
115
+ def append(contents)
116
+ write(contents,'a+')
117
+ self
118
+ end
119
+
120
+ def move(dest)
121
+ self.rename(dest)
122
+ dest.p
123
+ end
124
+
125
+ def tail(bytes)
126
+ return self.read if self.size < bytes
127
+ open('r') do |f|
128
+ f.seek(-bytes, IO::SEEK_END)
129
+ f.read
130
+ end
131
+ end
132
+
133
+ alias_method :mv, :move
134
+
135
+ def set_extension(ext)
136
+ "#{without_extension}.#{ext}".p
137
+ end
138
+
139
+ alias_method :change_extension, :set_extension
140
+
141
+ def without_extension
142
+ to_s[/^ (.+?) (\. ([^\.]+))? $/x, 1].p
143
+ end
144
+
145
+ def has_extension?(ext)
146
+ !!(self.to_s =~ /\.#{ext}$/)
147
+ end
148
+
149
+ def parent
150
+ super.p
151
+ end
152
+
153
+ alias_method :all_children, :children
154
+
155
+ def children
156
+ super.reject { |c| c.basename.to_s =~ /^\./ }
157
+ end
158
+
159
+ # only takes sym atm
160
+ def select(*args)
161
+ return args.map { |arg| select(arg) }.flatten.uniq if args.size > 1
162
+
163
+ case arg = args.first
164
+ when Symbol
165
+ Dir["#{self}/*.#{arg}"].map { |p| self.class.new(p) }
166
+ when Regexp
167
+ children.select { |child| child.to_s =~ arg }
168
+ else
169
+ Dir["#{self}/#{arg}"].map { |p| self.class.new(p) }
170
+ end
171
+ end
172
+
173
+ def empty?
174
+ directory? ? children.size == 0 : self.size == 0
175
+ end
176
+
177
+ def owner
178
+ Etc.getpwuid(File.stat(to_s).uid).name
179
+ end
180
+
181
+ def group
182
+ Etc.getgrgid(File.stat(to_s).gid).name
183
+ end
184
+
185
+ def inspect
186
+ super.sub('Pathname','Fancypath')
187
+ end
188
+
189
+ def to_fancypath
190
+ self
191
+ end
192
+
193
+ end
194
+
195
+ class Pathname
196
+ include Fancypath::Helpers
197
+ end
198
+ class String
199
+ include Fancypath::Helpers
200
+ end
@@ -0,0 +1,76 @@
1
+ class Inkan
2
+ attr_accessor :credit, :comment, :comment_suffix
3
+
4
+ def self.legitimate?(filename)
5
+ File.open(filename) do |file|
6
+ file_content = file.read
7
+ seal, content = if file_content[/\A#!/]
8
+ hashbang, seal, remaining_content = file_content.split("\n", 3)
9
+ [seal, "#{hashbang}\n#{remaining_content}"]
10
+ else
11
+ file_content.split("\n", 2)
12
+ end
13
+
14
+ !seal[/\s#{sha(content || '')}\s*$/].nil?
15
+ end
16
+ end
17
+
18
+ def self.seal(file)
19
+ new(file).tap {|inkan| yield inkan }.seal
20
+ end
21
+
22
+ def self.render
23
+ new(nil).tap {|inkan| yield inkan }.render
24
+ end
25
+
26
+ def self.sha(content)
27
+ require 'digest/sha1'
28
+ Digest::SHA1.hexdigest(content)
29
+ end
30
+
31
+ def initialize(file)
32
+ @file = file
33
+
34
+ # Set Defaults
35
+ @credit = 'Generated by Inkan'
36
+ @comment = '#'
37
+ @comment_suffix = ''
38
+ end
39
+
40
+ def print(string)
41
+ file_content << string
42
+ end
43
+
44
+ def puts(string)
45
+ file_content << string << "\n"
46
+ end
47
+
48
+ def seal
49
+ File.open(@file, 'w') do |f|
50
+ f.print render
51
+ end
52
+ end
53
+
54
+ def render
55
+ if file_content[/\A#!/]
56
+ hashbang, remaining_content = file_content.split("\n", 2)
57
+ "#{hashbang}\n#{render_seal}\n#{remaining_content}"
58
+ else
59
+ "#{render_seal}\n#{file_content}"
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def render_seal
66
+ "#{comment} #{credit}. #{sha} #{comment_suffix}"
67
+ end
68
+
69
+ def sha
70
+ self.class.sha(file_content)
71
+ end
72
+
73
+ def file_content
74
+ @file_content ||= ''
75
+ end
76
+ end