0e84fa57daa2ae21cdca40865972e066750cd66f
[ruby-cruxutils.git] / lib / cruxutils / port.rb
1 require "cruxutils/ohash.rb"
2 require "tempfile"
3 require "fileutils"
4
5 module CruxUtils
6
7 class Port
8         COMMENT_MAP = OHash.new
9         COMMENT_MAP["Description"] = :description
10         COMMENT_MAP["URL"] = :url
11         COMMENT_MAP["Packager"] = :packager
12         COMMENT_MAP["Maintainer"] = :maintainer
13         COMMENT_MAP["Depends on"] = :dependencies
14         COMMENT_MAP["Group"] = :group
15         COMMENT_MAP["Nice to have"] = :nice_to_have
16
17         def Port.open(dir)
18                 yield Port.new(dir)
19         end
20
21         def initialize(dir)
22                 @dir = dir
23
24                 @attribs = Hash.new { |h, k| h[k] = "" }
25
26                 @attribs[:dependencies] = Dependencies.new
27                 @attribs[:source] = Sources.new
28                 @attribs[:build] = BuildFunc.new
29
30                 read
31         end
32
33         def method_missing(meth, *args)
34                 if meth.to_s.match(/=$/) then
35                         m2 = meth.to_s[0...-1].to_sym
36                         @attribs[m2] = (args.length < 2 ? args.first : args)
37                 else
38                         @attribs[meth]
39                 end
40         end
41
42         def dependencies
43                 @attribs[:dependencies].uniq!
44                 @attribs[:dependencies]
45         end
46
47         def has_footprint?
48                 File.exist?(footprint)
49         end
50
51         def has_md5sum?
52                 File.exist?(md5sum)
53         end
54
55         def write
56                 Tempfile.open("pkgfile") do |file|
57                         COMMENT_MAP.each do |key, symbol|
58                                 value = @attribs[symbol]
59                                 next if value.empty?
60
61                                 file << "# #{key}: " << value << "\n"
62                         end
63
64                         file << "\n"
65
66                         vars = [:name, :version, :release, :source]
67                         vars.each do |var|
68                                 file << "#{var}=" <<
69                                         @attribs[var] << "\n"
70                         end
71
72                         file << "\n" << build << "\n"
73                         file.flush
74
75                         FileUtils.cp(file.path, pkgfile)
76                 end
77         end
78
79         private
80         def read
81                 vars = [:name, :version, :release]
82                 section = :comments
83
84                 cmt_map = OHash.new.replace(COMMENT_MAP)
85
86                 File.read(pkgfile).split("\n").each do |line|
87                         line.chomp!
88
89                         cmt_map.each do |key, symbol|
90                                 md = line.match(/^#\s*#{key}: (.+)$/)
91                                 unless md.nil?
92                                         @attribs[symbol].replace(md.captures.first.strip)
93                                         cmt_map.delete(key)
94                                 end
95                         end
96
97                         vars.each do |var|
98                                 md = line.match(/^#{var}=(.+)$/)
99                                 unless md.nil?
100                                         @attribs[var] = $1.strip
101                                         vars.delete(key)
102                                 end
103                         end
104
105                         # handle source array
106                         section = :void if line.match(/^\s*$/) && section != :build
107
108                         if section == :source && line.match(/(.+)\)$/)
109                                 @attribs[:source] << $1.strip
110                         elsif section == :source && line.match(/(.+)\\$/)
111                                 @attribs[:source] << $1.strip
112                         elsif line.match(/^source=\((.+)\)$/)
113                                 @attribs[:source] << $1.strip
114                         elsif line.match(/^source=\((.+)\\$/)
115                                 @attribs[:source] << $1.strip
116                                 section = :source
117                         end
118
119                         section = :end unless line.match(/^\}/).nil?
120                         if section == :build
121                                 # remove initial indentation
122                                 tmp = line.sub(/^(    |\t)/, "")
123
124                                 @attribs[:build] << (tmp || "")
125                         end
126                         section = :build unless line.match(/^build/).nil?
127                 end
128         end
129
130         def pkgfile
131                 File.join(@dir, "Pkgfile")
132         end
133
134         def footprint
135                 File.join(@dir, ".footprint")
136         end
137
138         def md5sum
139                 File.join(@dir, ".md5sum")
140         end
141 end
142
143 class Dependencies < Array
144         def to_s
145                 uniq.join(", ")
146         end
147
148         def replace(arg)
149                 if arg.is_a?(Array)
150                         super
151                 else
152                         clear
153
154                         arg.split(", ").each { |d| self << d.strip }
155                 end
156
157                 uniq!
158
159                 self
160         end
161 end
162
163 class Sources < Array
164         def to_s
165                 indent = " " * "source=(".length
166                 "(" + join(" \\\n" + indent) + ")"
167         end
168 end
169
170 class BuildFunc < Array
171         def to_s
172                 inject("build() {\n") do |a, line|
173                         if line != ""
174                                 line = "\t" + line
175                         end
176
177                         a << line << "\n"
178                         a
179                 end + "}"
180         end
181 end
182
183 end