pione 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. data/.gitignore +16 -13
  2. data/.travis.yml +1 -1
  3. data/History.txt +11 -0
  4. data/Rakefile +13 -0
  5. data/bin/pione-package +5 -0
  6. data/example/AbstractRule/package.yml +6 -0
  7. data/example/AbstractRule/scenario/a/output/message.txt +1 -0
  8. data/example/AbstractRule/scenario/a/scenario.yml +4 -0
  9. data/example/AbstractRule/scenario/b/output/message.txt +1 -0
  10. data/example/AbstractRule/scenario/b/scenario.yml +4 -0
  11. data/example/AbstractRule/scenario/c/output/message.txt +1 -0
  12. data/example/AbstractRule/scenario/c/scenario.yml +4 -0
  13. data/example/HelloWorld/package.yml +5 -1
  14. data/example/HelloWorld/scenario/scenario.yml +2 -1
  15. data/example/LoopByTouch/package.yml +4 -1
  16. data/example/MakePair/package.yml +6 -0
  17. data/example/MakePair/scenario/{input → case1/input}/1.i +0 -0
  18. data/example/MakePair/scenario/{input → case1/input}/2.i +0 -0
  19. data/example/MakePair/scenario/{input → case1/input}/3.i +0 -0
  20. data/example/MakePair/scenario/{input → case1/input}/4.i +0 -0
  21. data/example/MakePair/scenario/{input → case1/input}/5.i +0 -0
  22. data/example/MakePair/scenario/{output → case1/output}/comb-1-2.pair +0 -0
  23. data/example/MakePair/scenario/{output → case1/output}/comb-1-3.pair +0 -0
  24. data/example/MakePair/scenario/{output → case1/output}/comb-1-4.pair +0 -0
  25. data/example/MakePair/scenario/{output → case1/output}/comb-1-5.pair +0 -0
  26. data/example/MakePair/scenario/{output → case1/output}/comb-2-3.pair +0 -0
  27. data/example/MakePair/scenario/{output → case1/output}/comb-2-4.pair +0 -0
  28. data/example/MakePair/scenario/{output → case1/output}/comb-2-5.pair +0 -0
  29. data/example/MakePair/scenario/{output → case1/output}/comb-3-4.pair +0 -0
  30. data/example/MakePair/scenario/{output → case1/output}/comb-3-5.pair +0 -0
  31. data/example/MakePair/scenario/{output → case1/output}/comb-4-5.pair +0 -0
  32. data/example/MakePair/scenario/{output → case1/output}/perm-1-2.pair +0 -0
  33. data/example/MakePair/scenario/{output → case1/output}/perm-1-3.pair +0 -0
  34. data/example/MakePair/scenario/{output → case1/output}/perm-1-4.pair +0 -0
  35. data/example/MakePair/scenario/{output → case1/output}/perm-1-5.pair +0 -0
  36. data/example/MakePair/scenario/{output → case1/output}/perm-2-1.pair +0 -0
  37. data/example/MakePair/scenario/{output → case1/output}/perm-2-3.pair +0 -0
  38. data/example/MakePair/scenario/{output → case1/output}/perm-2-4.pair +0 -0
  39. data/example/MakePair/scenario/{output → case1/output}/perm-2-5.pair +0 -0
  40. data/example/MakePair/scenario/{output → case1/output}/perm-3-1.pair +0 -0
  41. data/example/MakePair/scenario/{output → case1/output}/perm-3-2.pair +0 -0
  42. data/example/MakePair/scenario/{output → case1/output}/perm-3-4.pair +0 -0
  43. data/example/MakePair/scenario/{output → case1/output}/perm-3-5.pair +0 -0
  44. data/example/MakePair/scenario/{output → case1/output}/perm-4-1.pair +0 -0
  45. data/example/MakePair/scenario/{output → case1/output}/perm-4-2.pair +0 -0
  46. data/example/MakePair/scenario/{output → case1/output}/perm-4-3.pair +0 -0
  47. data/example/MakePair/scenario/{output → case1/output}/perm-4-5.pair +0 -0
  48. data/example/MakePair/scenario/{output → case1/output}/perm-5-1.pair +0 -0
  49. data/example/MakePair/scenario/{output → case1/output}/perm-5-2.pair +0 -0
  50. data/example/MakePair/scenario/{output → case1/output}/perm-5-3.pair +0 -0
  51. data/example/MakePair/scenario/{output → case1/output}/perm-5-4.pair +0 -0
  52. data/example/MakePair/scenario/{output → case1/output}/succ-1-2.pair +0 -0
  53. data/example/MakePair/scenario/{output → case1/output}/succ-2-3.pair +0 -0
  54. data/example/MakePair/scenario/{output → case1/output}/succ-3-4.pair +0 -0
  55. data/example/MakePair/scenario/{output → case1/output}/succ-4-5.pair +0 -0
  56. data/example/MakePair/scenario/case1/scenario.yml +42 -0
  57. data/example/MakePair/scenario/case2/input/10.i +0 -0
  58. data/example/MakePair/scenario/case2/input/11.i +0 -0
  59. data/example/MakePair/scenario/case2/input/9.i +0 -0
  60. data/example/MakePair/scenario/case2/output/comb-10-11.pair +0 -0
  61. data/example/MakePair/scenario/case2/output/comb-9-10.pair +0 -0
  62. data/example/MakePair/scenario/case2/output/comb-9-11.pair +0 -0
  63. data/example/MakePair/scenario/case2/output/perm-10-11.pair +0 -0
  64. data/example/MakePair/scenario/case2/output/perm-10-9.pair +0 -0
  65. data/example/MakePair/scenario/case2/output/perm-11-10.pair +0 -0
  66. data/example/MakePair/scenario/case2/output/perm-11-9.pair +0 -0
  67. data/example/MakePair/scenario/case2/output/perm-9-10.pair +0 -0
  68. data/example/MakePair/scenario/case2/output/perm-9-11.pair +0 -0
  69. data/example/MakePair/scenario/case2/output/succ-10-11.pair +0 -0
  70. data/example/MakePair/scenario/case2/output/succ-9-10.pair +0 -0
  71. data/example/MakePair/scenario/case2/scenario.yml +17 -0
  72. data/example/MakePair/scenario/case3/input/1.i +0 -0
  73. data/example/MakePair/scenario/case3/input/3.i +0 -0
  74. data/example/MakePair/scenario/case3/input/5.i +0 -0
  75. data/example/MakePair/scenario/case3/input/7.i +0 -0
  76. data/example/MakePair/scenario/case3/input/9.i +0 -0
  77. data/example/MakePair/scenario/case3/output/comb-1-3.pair +0 -0
  78. data/example/MakePair/scenario/case3/output/comb-1-5.pair +0 -0
  79. data/example/MakePair/scenario/case3/output/comb-1-7.pair +0 -0
  80. data/example/MakePair/scenario/case3/output/comb-1-9.pair +0 -0
  81. data/example/MakePair/scenario/case3/output/comb-3-5.pair +0 -0
  82. data/example/MakePair/scenario/case3/output/comb-3-7.pair +0 -0
  83. data/example/MakePair/scenario/case3/output/comb-3-9.pair +0 -0
  84. data/example/MakePair/scenario/case3/output/comb-5-7.pair +0 -0
  85. data/example/MakePair/scenario/case3/output/comb-5-9.pair +0 -0
  86. data/example/MakePair/scenario/case3/output/comb-7-9.pair +0 -0
  87. data/example/MakePair/scenario/case3/output/perm-1-3.pair +0 -0
  88. data/example/MakePair/scenario/case3/output/perm-1-5.pair +0 -0
  89. data/example/MakePair/scenario/case3/output/perm-1-7.pair +0 -0
  90. data/example/MakePair/scenario/case3/output/perm-1-9.pair +0 -0
  91. data/example/MakePair/scenario/case3/output/perm-3-1.pair +0 -0
  92. data/example/MakePair/scenario/case3/output/perm-3-5.pair +0 -0
  93. data/example/MakePair/scenario/case3/output/perm-3-7.pair +0 -0
  94. data/example/MakePair/scenario/case3/output/perm-3-9.pair +0 -0
  95. data/example/MakePair/scenario/case3/output/perm-5-1.pair +0 -0
  96. data/example/MakePair/scenario/case3/output/perm-5-3.pair +0 -0
  97. data/example/MakePair/scenario/case3/output/perm-5-7.pair +0 -0
  98. data/example/MakePair/scenario/case3/output/perm-5-9.pair +0 -0
  99. data/example/MakePair/scenario/case3/output/perm-7-1.pair +0 -0
  100. data/example/MakePair/scenario/case3/output/perm-7-3.pair +0 -0
  101. data/example/MakePair/scenario/case3/output/perm-7-5.pair +0 -0
  102. data/example/MakePair/scenario/case3/output/perm-7-9.pair +0 -0
  103. data/example/MakePair/scenario/case3/output/perm-9-1.pair +0 -0
  104. data/example/MakePair/scenario/case3/output/perm-9-3.pair +0 -0
  105. data/example/MakePair/scenario/case3/output/perm-9-5.pair +0 -0
  106. data/example/MakePair/scenario/case3/output/perm-9-7.pair +0 -0
  107. data/example/MakePair/scenario/case3/scenario.yml +39 -0
  108. data/example/PegasusWMS/Merge/Merge.pione +21 -0
  109. data/example/PegasusWMS/Merge/package.yml +2 -0
  110. data/example/PegasusWMS/Pipeline/Pipeline.pione +20 -0
  111. data/example/PegasusWMS/Pipeline/package.yml +2 -0
  112. data/example/PegasusWMS/Split/Split.pione +27 -0
  113. data/example/PegasusWMS/Split/package.yml +2 -0
  114. data/example/ScoreAggregation/package.yml +4 -0
  115. data/example/ScoreAggregation/scenario/case1/scenario.yml +27 -1
  116. data/example/SerialProcessing/package.yml +5 -1
  117. data/example/SerialProcessing/scenario/scenario.yml +10 -0
  118. data/lib/pione.rb +20 -71
  119. data/lib/pione/agent.rb +17 -0
  120. data/lib/pione/agent/basic-agent.rb +2 -4
  121. data/lib/pione/command.rb +1 -0
  122. data/lib/pione/command/option.rb +4 -1
  123. data/lib/pione/command/pione-package.rb +97 -0
  124. data/lib/pione/command/pione-task-worker.rb +11 -7
  125. data/lib/pione/component.rb +5 -0
  126. data/lib/pione/component/document.rb +22 -5
  127. data/lib/pione/component/package-archiver.rb +92 -0
  128. data/lib/pione/component/package-expander.rb +37 -0
  129. data/lib/pione/component/package-filename.rb +38 -0
  130. data/lib/pione/component/package-reader.rb +276 -0
  131. data/lib/pione/component/package.rb +50 -162
  132. data/lib/pione/front.rb +14 -0
  133. data/lib/pione/location.rb +5 -0
  134. data/lib/pione/location/basic-location.rb +47 -274
  135. data/lib/pione/location/data-location.rb +328 -0
  136. data/lib/pione/location/dropbox-location.rb +30 -7
  137. data/lib/pione/location/exception.rb +38 -0
  138. data/lib/pione/location/ftp-location.rb +24 -13
  139. data/lib/pione/location/git-repository-location.rb +153 -0
  140. data/lib/pione/location/http-location.rb +65 -0
  141. data/lib/pione/location/https-location.rb +37 -0
  142. data/lib/pione/location/local-location.rb +24 -5
  143. data/lib/pione/parser.rb +14 -0
  144. data/lib/pione/patch.rb +10 -0
  145. data/lib/pione/patch/drb-patch.rb +2 -2
  146. data/lib/pione/relay.rb +11 -0
  147. data/lib/pione/system/file-cache.rb +1 -1
  148. data/lib/pione/system/global.rb +15 -0
  149. data/lib/pione/tuple-space.rb +11 -0
  150. data/lib/pione/tuple-space/tuple-space-server.rb +1 -1
  151. data/lib/pione/util.rb +1 -0
  152. data/lib/pione/util/error-report.rb +7 -0
  153. data/lib/pione/util/misc.rb +2 -2
  154. data/lib/pione/util/zip.rb +60 -0
  155. data/lib/pione/version.rb +1 -1
  156. data/pione.gemspec +5 -1
  157. data/test/agent/spec_rule-provider.rb +2 -2
  158. data/test/command/spec_pione-package.rb +15 -0
  159. data/test/component/spec_document.rb +2 -2
  160. data/test/component/spec_package-archiver.rb +27 -0
  161. data/test/component/spec_package-expander.rb +11 -0
  162. data/test/component/spec_package-filename.rb +79 -0
  163. data/test/component/spec_package-reader.rb +100 -0
  164. data/test/component/spec_package.rb +50 -33
  165. data/test/location/http-behavior.rb +59 -0
  166. data/test/location/location-behavior.rb +8 -0
  167. data/test/location/spec_basic-location.rb +5 -1
  168. data/test/location/spec_git-repository-location.rb +143 -0
  169. data/test/location/spec_http-location.rb +28 -0
  170. data/test/location/spec_http-location/a.txt +1 -0
  171. data/test/location/spec_http-location/b.txt +1 -0
  172. data/test/location/spec_http-location/c.txt +1 -0
  173. data/test/location/spec_http-location/dir/d.txt +1 -0
  174. data/test/location/spec_https-location.rb +37 -0
  175. data/test/rule-handler/spec_flow-handler.rb +1 -1
  176. data/test/rule-handler/spec_update-criteria.rb +1 -1
  177. data/test/test-data/package/HelloWorld+v0.1.0.ppg +0 -0
  178. data/test/test-data/package/HelloWorld-gitrepos.zip +0 -0
  179. data/test/test-data/package/HelloWorld/HelloWorld.pione +5 -0
  180. data/test/test-data/package/HelloWorld/package.yml +6 -0
  181. data/test/test-data/package/HelloWorld/scenario/output/message.txt +1 -0
  182. data/test/test-data/package/HelloWorld/scenario/scenario.yml +3 -0
  183. data/test/test-data/package/TestPackage1+v0.1.0.ppg +0 -0
  184. data/test/{component/spec_package/TestPackage → test-data/package/TestPackage1}/Test.pione +3 -1
  185. data/test/test-data/package/TestPackage1/bin/count +11 -0
  186. data/test/test-data/package/TestPackage1/package.yml +9 -0
  187. data/test/{component/spec_package/TestPackage → test-data/package/TestPackage1}/scenario/case1/input/1.txt +0 -0
  188. data/test/test-data/package/TestPackage1/scenario/case1/output/1.count +1 -0
  189. data/test/test-data/package/TestPackage1/scenario/case1/scenario.yml +6 -0
  190. data/test/test-data/package/TestPackage1/scenario/case2/input/1.txt +2 -0
  191. data/test/test-data/package/TestPackage1/scenario/case2/input/2.txt +1 -0
  192. data/test/test-data/package/TestPackage1/scenario/case2/input/3.txt +3 -0
  193. data/test/test-data/package/TestPackage1/scenario/case2/output/1.count +1 -0
  194. data/test/test-data/package/TestPackage1/scenario/case2/output/2.count +1 -0
  195. data/test/test-data/package/TestPackage1/scenario/case2/output/3.count +1 -0
  196. data/test/test-data/package/TestPackage1/scenario/case2/scenario.yml +10 -0
  197. data/test/test-data/package/TestPackage1/scenario/case3/input/a.txt +1 -0
  198. data/test/test-data/package/TestPackage1/scenario/case3/input/b.txt +1 -0
  199. data/test/test-data/package/TestPackage1/scenario/case3/output/a.count +1 -0
  200. data/test/test-data/package/TestPackage1/scenario/case3/output/b.count +1 -0
  201. data/test/test-data/package/TestPackage1/scenario/case3/scenario.yml +8 -0
  202. data/test/test-util.rb +10 -146
  203. data/test/test-util/command.rb +53 -0
  204. data/test/test-util/package.rb +9 -0
  205. data/test/test-util/parser.rb +45 -0
  206. data/test/test-util/transformer.rb +50 -0
  207. data/test/test-util/webserver.rb +43 -0
  208. data/test/util/spec_error-report.rb +12 -3
  209. data/test/util/spec_zip.rb +36 -0
  210. metadata +282 -54
  211. data/example/MakePair/scenario/scenario.yml +0 -1
  212. data/test/component/spec_package/TestPackage/bin/count +0 -3
  213. data/test/component/spec_package/TestPackage/package.yml +0 -7
  214. data/test/component/spec_package/TestPackage/scenario/case1/scenario.yml +0 -1
@@ -6,3 +6,8 @@ end
6
6
  require 'pione/component/rule'
7
7
  require 'pione/component/document'
8
8
  require 'pione/component/package'
9
+ require 'pione/component/package-filename'
10
+ require 'pione/component/package-reader'
11
+ require 'pione/component/package-archiver'
12
+ require 'pione/component/package-expander'
13
+
@@ -12,15 +12,31 @@ module Pione
12
12
 
13
13
  class Document < StructX
14
14
  class << self
15
- # Load a PIONE rule document.
15
+ # Load a PIONE rule document as file.
16
16
  #
17
- # @param location [Location,String]
17
+ # @param location [BasicLocation]
18
18
  # location of the PIONE document
19
+ # @param package_name [String]
20
+ # package name
21
+ # @param package_path [String]
22
+ # relative path of the document in package
19
23
  # @return [Component::Document]
20
24
  # the document
21
- def load(src, package_name="Main")
22
- src = src.read if src.kind_of?(Location::BasicLocation)
25
+ def load(src, package_name="Main", package_path="Unknown.pione")
26
+ parse(src.read, package_name, package_path)
27
+ end
23
28
 
29
+ # Parse a PIONE rule document as string.
30
+ #
31
+ # @param location [String]
32
+ # PIONE document
33
+ # @param package_name [String]
34
+ # package name
35
+ # @param path [String]
36
+ # relative path of the document
37
+ # @return [Component::Document]
38
+ # the document as Ruby object
39
+ def parse(src, package_name="Main", package_path="Unknown.pione")
24
40
  # parse the document and build the model
25
41
  parser = Parser::DocumentParser.new
26
42
  transformer = Transformer::DocumentTransformer.new(package_name)
@@ -38,13 +54,14 @@ module Pione
38
54
  # set document parameters into rules
39
55
  rules.each {|rule| rule.condition.params.merge!(params)}
40
56
 
41
- return new(package_name, rules, params)
57
+ return new(package_name, rules, params, package_path)
42
58
  end
43
59
  end
44
60
 
45
61
  member :package_name
46
62
  member :rules
47
63
  member :params
64
+ member :package_path
48
65
 
49
66
  # Find the named rule.
50
67
  #
@@ -0,0 +1,92 @@
1
+ module Pione
2
+ module Component
3
+ # PackageArchiver makes PPG file as PIONE archive.
4
+ class PackageArchiver
5
+ attr_reader :location
6
+
7
+ # @param location [BasicLoaction]
8
+ # the location of package
9
+ def initialize(location, option={})
10
+ if location.location_type == :git_repository
11
+ location = location + option
12
+ end
13
+ @package = PackageReader.read(location)
14
+ @location = @package.location
15
+ @tag = option[:tag]
16
+ @branch = option[:branch]
17
+ end
18
+
19
+ # Create a package archive file.
20
+ #
21
+ # @param output_location [BasicLocation]
22
+ # the location of output directory
23
+ def archive(output_location)
24
+ output = output_location + filename
25
+ path = Temppath.create
26
+ Zip::Archive.open(path.to_s, Zip::CREATE) do |ar|
27
+ archive_package_info(ar)
28
+ archive_documents(ar)
29
+ archive_scenarios(ar)
30
+ end
31
+ Location[path].copy(output)
32
+ return output
33
+ end
34
+
35
+ private
36
+
37
+ def filename
38
+ PackageFilename.new(
39
+ package_name: @package.name,
40
+ edition: @package.edition,
41
+ tag: @tag || @branch || @package.tag,
42
+ hash_id: @package.hash_id
43
+ ).to_s
44
+ end
45
+
46
+ def archive_package_info(ar)
47
+ ar.add_buffer("package.yml", (@location + "package.yml").read)
48
+ end
49
+
50
+ def archive_documents(ar)
51
+ @package.documents.each do |doc|
52
+ ar.add_buffer(doc.package_path, (@location + doc.package_path).read)
53
+ end
54
+ end
55
+
56
+ def archive_scenarios(ar)
57
+ @package.scenarios.each do |scenario|
58
+ ar.add_dir(scenario.package_path)
59
+ archive_scenario_info(ar, scenario)
60
+ archive_scenario_inputs(ar, scenario)
61
+ archive_scenario_outputs(ar, scenario)
62
+ end
63
+ end
64
+
65
+ def archive_scenario_info(ar, scenario)
66
+ package_path = File.join(scenario.package_path, "scenario.yml")
67
+ location = @location + scenario.package_path + "scenario.yml"
68
+ ar.add_buffer(package_path, location.read)
69
+ end
70
+
71
+ def archive_scenario_inputs(ar, scenario)
72
+ if not(scenario.inputs.empty?)
73
+ ar.add_dir(File.join(scenario.package_path, "input"))
74
+ scenario.inputs.each do |input|
75
+ package_path = File.join(scenario.package_path, "input", input.basename)
76
+ ar.add_buffer(package_path, input.read)
77
+ end
78
+ end
79
+ end
80
+
81
+ def archive_scenario_outputs(ar, scenario)
82
+ if not(scenario.outputs.empty?)
83
+ ar.add_dir(File.join(scenario.package_path, "output"))
84
+ scenario.outputs.each do |output|
85
+ package_path = File.join(scenario.package_path, "output", output.basename)
86
+ ar.add_buffer(package_path, output.read)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,37 @@
1
+ module Pione
2
+ module Component
3
+ # PackageExpander expands package files from archive.
4
+ class PackageExpander
5
+ attr_reader :location
6
+
7
+ # @param location [BasicLoaction]
8
+ # package location
9
+ def initialize(location)
10
+ @location = location
11
+ end
12
+
13
+ def expand(output)
14
+ location = @location.local
15
+
16
+ # expand
17
+ Zip::Archive.open(location.path.to_s) do |ar|
18
+ ar.each do |file|
19
+ unless file.directory?
20
+ (output + file.name).write(file.read)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def valid_filename?
29
+ filename = @location.basename
30
+ if File.extname(filename) == ".ppg"
31
+ identifiers = filename.split("-")
32
+ identifiers[1]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ module Pione
2
+ module Component
3
+ class PackageFilenameParser < Parslet::Parser
4
+ root(:filename)
5
+
6
+ rule(:filename) { package_name.maybe >> edition.maybe >> tag.maybe >> hash_id.maybe >> ext }
7
+
8
+ rule(:package_name) { ((str("(") | str(".") | str("+") | str("@")).absent? >> any).repeat(1).as(:package_name) }
9
+ rule(:edition) { str("(") >> (str(")").absent? >> any).repeat(1).as(:edition) >> str(")") }
10
+ rule(:tag) { str("+") >> ((ext | str("@")).absent? >> any).repeat(1).as(:tag) }
11
+ rule(:hash_id) { str("@") >> match('[0-9a-fA-F]').repeat(1).as(:hash_id) }
12
+ rule(:ext) { str(".ppg") }
13
+ end
14
+
15
+ class PackageFilename < StructX
16
+ member :package_name
17
+ member :edition, default: "origin"
18
+ member :tag
19
+ member :hash_id
20
+
21
+ class << self
22
+ def parse(str)
23
+ new(PackageFilenameParser.new.parse(str))
24
+ end
25
+ end
26
+
27
+ def to_s
28
+ name = ""
29
+ name << package_name
30
+ name << "(%s)" % edition if edition and edition != "origin"
31
+ name << "+%s" % tag if tag
32
+ name << "@%s" % hash_id if hash_id
33
+ name + ".ppg"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,276 @@
1
+ module Pione
2
+ module Component
3
+ module PackageTypeClassifier
4
+ class << self
5
+ # Distinguish the type of package based on the location.
6
+ #
7
+ # @param [BasicLocation]
8
+ # location of the package
9
+ # @return [Symbol]
10
+ # package type
11
+ def classify(location)
12
+ return :git if git?(location)
13
+ return :archive if archive?(location)
14
+ return :document if document?(location)
15
+ return :directory
16
+ end
17
+
18
+ private
19
+
20
+ # Return true if the location represents git package.
21
+ def git?(location)
22
+ location.location_type == :git_repository
23
+ end
24
+
25
+ # Return true if the location represents archive package.
26
+ def archive?(location)
27
+ location.file? and location.extname == ".ppg"
28
+ end
29
+
30
+ # Return true if the location represents document package.
31
+ def document?(location)
32
+ location.file? and location.extname == ".pione"
33
+ end
34
+ end
35
+ end
36
+
37
+ # PackageReader is a reader for packages.
38
+ class PackageReader
39
+ class << self
40
+ # Read a pacakge from the location.
41
+ #
42
+ # @param location [Location::BasicLocation]
43
+ # location of package
44
+ # @return [Package]
45
+ # the package
46
+ def read(location)
47
+ new(location).read
48
+ end
49
+ end
50
+
51
+ attr_reader :location
52
+ attr_reader :type
53
+
54
+ # @param location [BasicLocation]
55
+ # package location
56
+ def initialize(location)
57
+ @location = location
58
+ @type = PackageTypeClassifier.classify(location)
59
+ end
60
+
61
+ def read
62
+ case @type
63
+ when :directory
64
+ read_directory
65
+ when :git
66
+ read_git
67
+ when :archive
68
+ read_archive
69
+ when :document
70
+ read_document
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ # Return the location of package information file.
77
+ def spec_location
78
+ @location + "package.yml"
79
+ end
80
+
81
+ # Read package directory.
82
+ #
83
+ # @return [Package]
84
+ # the package
85
+ def read_directory
86
+ info = read_package_info
87
+ Package.new(
88
+ location: @location,
89
+ info: info,
90
+ bin: @location + "bin",
91
+ documents: find_documents(info["PackageName"], info["Documents"]),
92
+ scenario_paths: find_scenario_paths(info["Scenarios"])
93
+ )
94
+ end
95
+
96
+ # Read git package.
97
+ def read_git
98
+ GitPackageReader.read(@location)
99
+ end
100
+
101
+ # Read PIONE archive.
102
+ #
103
+ # @return [Package]
104
+ # the package
105
+ def read_archive
106
+ self.class.read(ArchivePackageReader.read(@location))
107
+ end
108
+
109
+ # Read PIONE document.
110
+ #
111
+ # @return [Package]
112
+ # the package
113
+ def read_document
114
+ info = {"PackageName" => "Main"}
115
+ document = Component::Document.load(@location, "Main")
116
+ Package.new(info: info, documents: [document])
117
+ end
118
+
119
+ # Read the informations from the package location.
120
+ #
121
+ # @return [Hash]
122
+ # package information table
123
+ def read_package_info
124
+ YAML.load((@location + "package.yml").read)
125
+ rescue Location::NotFound
126
+ raise InvalidPackageError.new(self, "package.yml not found in %s" % @location.uri)
127
+ end
128
+
129
+ # Find scenarios from the package location.
130
+ #
131
+ # @return [Array<PackageScenario>]
132
+ # scenarios
133
+ def find_scenario_paths(scenarios)
134
+ return [] if scenarios.nil?
135
+ scenarios.select do |path|
136
+ (@location + path + "scenario.yml").exist?
137
+ end.uniq.compact
138
+ end
139
+
140
+ # Find documents from the packcage location.
141
+ #
142
+ # @return [Array<Document>]
143
+ # documents
144
+ def find_documents(package_name, document_names)
145
+ document_names.map do |name|
146
+ Document.load(@location + name, package_name, name)
147
+ end
148
+ end
149
+ end
150
+
151
+ # PackageScenarioReader is a reader for loading scenarios.
152
+ class PackageScenarioReader
153
+ # Read scenario from the location.
154
+ def self.read(location, package_path)
155
+ new(location, package_path).read
156
+ end
157
+
158
+ attr_reader :location
159
+ attr_reader :package_path
160
+
161
+ # @param location [Location]
162
+ # the scenario location
163
+ def initialize(location, package_path)
164
+ @location = location
165
+ @package_path = package_path
166
+ end
167
+
168
+ # Return the location of scenario information file.
169
+ def info_location
170
+ @location + @package_path + "scenario.yml"
171
+ end
172
+
173
+ # Read scenario files.
174
+ #
175
+ # @return [PackageScenario]
176
+ # the scenario
177
+ def read
178
+ begin
179
+ info = read_scenario_informations
180
+ PackageScenario.new(@location, @package_path, info)
181
+ rescue
182
+ nil
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ # Read scenario informations.
189
+ #
190
+ # @return [Hash]
191
+ # scenario information table
192
+ def read_scenario_informations
193
+ path = info_location
194
+ if path.exist?
195
+ YAML.load(path.read)
196
+ else
197
+ {"ScenarioName" => (@location + @package_path).basename}
198
+ end
199
+ end
200
+ end
201
+
202
+ class GitPackageReader
203
+ class << self
204
+ def read(location)
205
+ new(location).read
206
+ end
207
+ end
208
+
209
+ def initialize(location, option={})
210
+ @location = location
211
+ @package_name = option[:package_name]
212
+ @edition = option[:edition] || "origin"
213
+ @branch = option[:branch]
214
+ @tag = option[:tag]
215
+ @hash_id = option[:hash_id]
216
+
217
+ @digest = Digest::SHA1.hexdigest(@location.address)
218
+ end
219
+
220
+ def read
221
+ if cache_location = find_cache_location
222
+ return PackageReader.read(cache_location)
223
+ else
224
+ Location[Temppath.mkdir].tap do |tmp|
225
+ @location.export(tmp)
226
+ _package = PackageReader.read(tmp)
227
+ cache_location = Global.git_package_directory + dirname(_package)
228
+ cache_location.mkdir
229
+ tmp.entries.each {|entry| entry.move(cache_location)}
230
+ return PackageReader.read(cache_location)
231
+ end
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def find_cache_location
238
+ begin
239
+ Global.git_package_directory.entries.find do |entry|
240
+ entry.basename.to_s.split("_").last.include?(@location.compact_hash_id)
241
+ end
242
+ rescue Pione::Location::NotFound
243
+ return nil
244
+ end
245
+ end
246
+
247
+ # Return the cache directory name.
248
+ def dirname(package)
249
+ "%s(%s)_%s" % [package.name, package.edition, @location.compact_hash_id]
250
+ end
251
+ end
252
+
253
+ class ArchivePackageReader
254
+ class << self
255
+ def read(location)
256
+ new(location).expand
257
+ end
258
+ end
259
+
260
+ def initialize(location)
261
+ @location = location
262
+ end
263
+
264
+ def expand
265
+ cache = Global.archive_package_cache_dir + cache_name
266
+ PackageExpander.new(@location).expand(cache)
267
+ return cache
268
+ end
269
+
270
+ def cache_name
271
+ fname = PackageFilename.parse(@location.basename)
272
+ "%s(%s)_%s" % [fname.package_name, fname.edition, @location.sha1]
273
+ end
274
+ end
275
+ end
276
+ end