bio 1.2.1 → 1.3.0

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 (259) hide show
  1. data/ChangeLog +3421 -0
  2. data/KNOWN_ISSUES.rdoc +88 -0
  3. data/README.rdoc +252 -0
  4. data/README_DEV.rdoc +285 -0
  5. data/Rakefile +143 -0
  6. data/bin/bioruby +0 -0
  7. data/bin/br_biofetch.rb +0 -0
  8. data/bin/br_bioflat.rb +12 -1
  9. data/bin/br_biogetseq.rb +0 -0
  10. data/bin/br_pmfetch.rb +4 -3
  11. data/bioruby.gemspec +477 -0
  12. data/bioruby.gemspec.erb +117 -0
  13. data/doc/Changes-0.7.rd +7 -0
  14. data/doc/Changes-1.3.rdoc +239 -0
  15. data/doc/Tutorial.rd +296 -184
  16. data/doc/Tutorial.rd.html +1031 -0
  17. data/doc/Tutorial.rd.ja +111 -45
  18. data/doc/Tutorial.rd.ja.html +2225 -0
  19. data/doc/bioruby.css +281 -0
  20. data/extconf.rb +2 -0
  21. data/lib/bio.rb +29 -4
  22. data/lib/bio/appl/blast.rb +306 -121
  23. data/lib/bio/appl/blast/ddbj.rb +142 -0
  24. data/lib/bio/appl/blast/format0.rb +35 -25
  25. data/lib/bio/appl/blast/format8.rb +2 -2
  26. data/lib/bio/appl/blast/genomenet.rb +263 -0
  27. data/lib/bio/appl/blast/ncbioptions.rb +220 -0
  28. data/lib/bio/appl/blast/remote.rb +106 -0
  29. data/lib/bio/appl/blast/report.rb +260 -9
  30. data/lib/bio/appl/blast/rexml.rb +12 -5
  31. data/lib/bio/appl/blast/rpsblast.rb +277 -0
  32. data/lib/bio/appl/blast/wublast.rb +133 -12
  33. data/lib/bio/appl/blast/xmlparser.rb +35 -18
  34. data/lib/bio/appl/blat/report.rb +46 -5
  35. data/lib/bio/appl/emboss.rb +62 -13
  36. data/lib/bio/appl/fasta.rb +9 -11
  37. data/lib/bio/appl/genscan/report.rb +3 -3
  38. data/lib/bio/appl/hmmer.rb +1 -1
  39. data/lib/bio/appl/hmmer/report.rb +10 -10
  40. data/lib/bio/appl/paml/baseml.rb +95 -0
  41. data/lib/bio/appl/paml/baseml/report.rb +32 -0
  42. data/lib/bio/appl/paml/codeml.rb +242 -0
  43. data/lib/bio/appl/paml/codeml/rates.rb +67 -0
  44. data/lib/bio/appl/paml/codeml/report.rb +67 -0
  45. data/lib/bio/appl/paml/common.rb +348 -0
  46. data/lib/bio/appl/paml/common_report.rb +38 -0
  47. data/lib/bio/appl/paml/yn00.rb +103 -0
  48. data/lib/bio/appl/paml/yn00/report.rb +32 -0
  49. data/lib/bio/appl/psort.rb +2 -2
  50. data/lib/bio/appl/pts1.rb +5 -5
  51. data/lib/bio/appl/tmhmm/report.rb +10 -1
  52. data/lib/bio/command.rb +297 -41
  53. data/lib/bio/compat/features.rb +157 -0
  54. data/lib/bio/compat/references.rb +128 -0
  55. data/lib/bio/db/biosql/biosql_to_biosequence.rb +67 -0
  56. data/lib/bio/db/biosql/sequence.rb +508 -0
  57. data/lib/bio/db/embl/common.rb +28 -12
  58. data/lib/bio/db/embl/embl.rb +107 -9
  59. data/lib/bio/db/embl/embl_to_biosequence.rb +85 -0
  60. data/lib/bio/db/embl/format_embl.rb +190 -0
  61. data/lib/bio/db/embl/sptr.rb +15 -16
  62. data/lib/bio/db/fantom.rb +6 -8
  63. data/lib/bio/db/fasta.rb +10 -507
  64. data/lib/bio/db/fasta/defline.rb +532 -0
  65. data/lib/bio/db/fasta/fasta_to_biosequence.rb +63 -0
  66. data/lib/bio/db/fasta/format_fasta.rb +97 -0
  67. data/lib/bio/db/genbank/common.rb +25 -8
  68. data/lib/bio/db/genbank/format_genbank.rb +187 -0
  69. data/lib/bio/db/genbank/genbank.rb +36 -1
  70. data/lib/bio/db/genbank/genbank_to_biosequence.rb +86 -0
  71. data/lib/bio/db/gff.rb +1791 -119
  72. data/lib/bio/db/kegg/glycan.rb +2 -6
  73. data/lib/bio/db/lasergene.rb +3 -3
  74. data/lib/bio/db/medline.rb +4 -1
  75. data/lib/bio/db/newick.rb +10 -10
  76. data/lib/bio/db/pdb/chain.rb +6 -2
  77. data/lib/bio/db/pdb/pdb.rb +12 -3
  78. data/lib/bio/db/rebase.rb +7 -8
  79. data/lib/bio/db/soft.rb +3 -3
  80. data/lib/bio/feature.rb +1 -88
  81. data/lib/bio/io/biosql/biodatabase.rb +64 -0
  82. data/lib/bio/io/biosql/bioentry.rb +29 -0
  83. data/lib/bio/io/biosql/bioentry_dbxref.rb +11 -0
  84. data/lib/bio/io/biosql/bioentry_path.rb +12 -0
  85. data/lib/bio/io/biosql/bioentry_qualifier_value.rb +10 -0
  86. data/lib/bio/io/biosql/bioentry_reference.rb +10 -0
  87. data/lib/bio/io/biosql/bioentry_relationship.rb +10 -0
  88. data/lib/bio/io/biosql/biosequence.rb +11 -0
  89. data/lib/bio/io/biosql/comment.rb +7 -0
  90. data/lib/bio/io/biosql/config/database.yml +20 -0
  91. data/lib/bio/io/biosql/dbxref.rb +13 -0
  92. data/lib/bio/io/biosql/dbxref_qualifier_value.rb +12 -0
  93. data/lib/bio/io/biosql/location.rb +32 -0
  94. data/lib/bio/io/biosql/location_qualifier_value.rb +11 -0
  95. data/lib/bio/io/biosql/ontology.rb +10 -0
  96. data/lib/bio/io/biosql/reference.rb +9 -0
  97. data/lib/bio/io/biosql/seqfeature.rb +32 -0
  98. data/lib/bio/io/biosql/seqfeature_dbxref.rb +11 -0
  99. data/lib/bio/io/biosql/seqfeature_path.rb +11 -0
  100. data/lib/bio/io/biosql/seqfeature_qualifier_value.rb +20 -0
  101. data/lib/bio/io/biosql/seqfeature_relationship.rb +11 -0
  102. data/lib/bio/io/biosql/taxon.rb +12 -0
  103. data/lib/bio/io/biosql/taxon_name.rb +9 -0
  104. data/lib/bio/io/biosql/term.rb +27 -0
  105. data/lib/bio/io/biosql/term_dbxref.rb +11 -0
  106. data/lib/bio/io/biosql/term_path.rb +12 -0
  107. data/lib/bio/io/biosql/term_relationship.rb +13 -0
  108. data/lib/bio/io/biosql/term_relationship_term.rb +11 -0
  109. data/lib/bio/io/biosql/term_synonym.rb +10 -0
  110. data/lib/bio/io/das.rb +7 -7
  111. data/lib/bio/io/ddbjxml.rb +57 -0
  112. data/lib/bio/io/ensembl.rb +2 -2
  113. data/lib/bio/io/fetch.rb +28 -14
  114. data/lib/bio/io/flatfile.rb +17 -853
  115. data/lib/bio/io/flatfile/autodetection.rb +545 -0
  116. data/lib/bio/io/flatfile/buffer.rb +237 -0
  117. data/lib/bio/io/flatfile/index.rb +17 -7
  118. data/lib/bio/io/flatfile/indexer.rb +30 -12
  119. data/lib/bio/io/flatfile/splitter.rb +297 -0
  120. data/lib/bio/io/hinv.rb +442 -0
  121. data/lib/bio/io/keggapi.rb +2 -2
  122. data/lib/bio/io/ncbirest.rb +733 -0
  123. data/lib/bio/io/pubmed.rb +34 -80
  124. data/lib/bio/io/registry.rb +2 -2
  125. data/lib/bio/io/sql.rb +178 -357
  126. data/lib/bio/io/togows.rb +458 -0
  127. data/lib/bio/location.rb +106 -11
  128. data/lib/bio/pathway.rb +120 -14
  129. data/lib/bio/reference.rb +115 -101
  130. data/lib/bio/sequence.rb +164 -183
  131. data/lib/bio/sequence/adapter.rb +108 -0
  132. data/lib/bio/sequence/common.rb +22 -45
  133. data/lib/bio/sequence/compat.rb +2 -2
  134. data/lib/bio/sequence/dblink.rb +54 -0
  135. data/lib/bio/sequence/format.rb +254 -77
  136. data/lib/bio/sequence/format_raw.rb +23 -0
  137. data/lib/bio/shell.rb +3 -1
  138. data/lib/bio/shell/core.rb +2 -2
  139. data/lib/bio/shell/plugin/entry.rb +33 -4
  140. data/lib/bio/shell/plugin/ncbirest.rb +64 -0
  141. data/lib/bio/shell/plugin/togows.rb +40 -0
  142. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/bioruby_generator.rb +0 -0
  143. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/_classes.rhtml +0 -0
  144. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/_log.rhtml +0 -0
  145. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/_methods.rhtml +0 -0
  146. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/_modules.rhtml +0 -0
  147. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/_variables.rhtml +0 -0
  148. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby-bg.gif +0 -0
  149. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby-gem.png +0 -0
  150. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby-link.gif +0 -0
  151. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby.css +0 -0
  152. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby.rhtml +0 -0
  153. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby_controller.rb +0 -0
  154. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/bioruby_helper.rb +0 -0
  155. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/commands.rhtml +0 -0
  156. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/history.rhtml +0 -0
  157. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/index.rhtml +0 -0
  158. data/lib/bio/shell/rails/vendor/plugins/{generators → bioruby/generators}/bioruby/templates/spinner.gif +0 -0
  159. data/lib/bio/tree.rb +4 -2
  160. data/lib/bio/util/color_scheme.rb +2 -2
  161. data/lib/bio/util/contingency_table.rb +2 -2
  162. data/lib/bio/util/restriction_enzyme.rb +2 -2
  163. data/lib/bio/util/restriction_enzyme/single_strand.rb +6 -5
  164. data/lib/bio/version.rb +25 -0
  165. data/rdoc.zsh +8 -0
  166. data/sample/any2fasta.rb +0 -0
  167. data/sample/biofetch.rb +0 -0
  168. data/sample/dbget +0 -0
  169. data/sample/demo_sequence.rb +158 -0
  170. data/sample/enzymes.rb +0 -0
  171. data/sample/fasta2tab.rb +0 -0
  172. data/sample/fastagrep.rb +72 -0
  173. data/sample/fastasort.rb +54 -0
  174. data/sample/fsplit.rb +0 -0
  175. data/sample/gb2fasta.rb +2 -3
  176. data/sample/gb2tab.rb +0 -0
  177. data/sample/gbtab2mysql.rb +0 -0
  178. data/sample/genes2nuc.rb +0 -0
  179. data/sample/genes2pep.rb +0 -0
  180. data/sample/genes2tab.rb +0 -0
  181. data/sample/genome2rb.rb +0 -0
  182. data/sample/genome2tab.rb +0 -0
  183. data/sample/goslim.rb +0 -0
  184. data/sample/gt2fasta.rb +0 -0
  185. data/sample/na2aa.rb +34 -0
  186. data/sample/pmfetch.rb +0 -0
  187. data/sample/pmsearch.rb +0 -0
  188. data/sample/ssearch2tab.rb +0 -0
  189. data/sample/tfastx2tab.rb +0 -0
  190. data/sample/vs-genes.rb +0 -0
  191. data/setup.rb +1596 -0
  192. data/test/data/blast/blastp-multi.m7 +188 -0
  193. data/test/data/command/echoarg2.bat +1 -0
  194. data/test/data/paml/codeml/control_file.txt +30 -0
  195. data/test/data/paml/codeml/output.txt +78 -0
  196. data/test/data/paml/codeml/rates +217 -0
  197. data/test/data/rpsblast/misc.rpsblast +193 -0
  198. data/test/data/soft/GDS100_partial.soft +0 -0
  199. data/test/data/soft/GSE3457_family_partial.soft +0 -0
  200. data/test/functional/bio/appl/test_pts1.rb +115 -0
  201. data/test/functional/bio/io/test_ensembl.rb +123 -80
  202. data/test/functional/bio/io/test_togows.rb +267 -0
  203. data/test/functional/bio/sequence/test_output_embl.rb +51 -0
  204. data/test/functional/bio/test_command.rb +301 -0
  205. data/test/runner.rb +17 -1
  206. data/test/unit/bio/appl/blast/test_ncbioptions.rb +112 -0
  207. data/test/unit/bio/appl/blast/test_report.rb +753 -35
  208. data/test/unit/bio/appl/blast/test_rpsblast.rb +398 -0
  209. data/test/unit/bio/appl/paml/codeml/test_rates.rb +45 -0
  210. data/test/unit/bio/appl/paml/codeml/test_report.rb +45 -0
  211. data/test/unit/bio/appl/paml/test_codeml.rb +174 -0
  212. data/test/unit/bio/appl/test_blast.rb +135 -4
  213. data/test/unit/bio/appl/test_fasta.rb +2 -2
  214. data/test/unit/bio/appl/test_pts1.rb +1 -64
  215. data/test/unit/bio/db/embl/test_common.rb +15 -15
  216. data/test/unit/bio/db/embl/test_embl.rb +4 -4
  217. data/test/unit/bio/db/embl/test_embl_rel89.rb +5 -5
  218. data/test/unit/bio/db/embl/test_embl_to_bioseq.rb +203 -0
  219. data/test/unit/bio/db/embl/test_sptr.rb +38 -1
  220. data/test/unit/bio/db/pdb/test_pdb.rb +2 -2
  221. data/test/unit/bio/db/test_gff.rb +1151 -25
  222. data/test/unit/bio/db/test_medline.rb +127 -0
  223. data/test/unit/bio/db/test_nexus.rb +5 -1
  224. data/test/unit/bio/db/test_prosite.rb +4 -4
  225. data/test/unit/bio/io/flatfile/test_autodetection.rb +375 -0
  226. data/test/unit/bio/io/flatfile/test_buffer.rb +251 -0
  227. data/test/unit/bio/io/flatfile/test_splitter.rb +369 -0
  228. data/test/unit/bio/io/test_ddbjxml.rb +8 -3
  229. data/test/unit/bio/io/test_fastacmd.rb +5 -5
  230. data/test/unit/bio/io/test_flatfile.rb +357 -106
  231. data/test/unit/bio/io/test_soapwsdl.rb +2 -2
  232. data/test/unit/bio/io/test_togows.rb +161 -0
  233. data/test/unit/bio/sequence/test_common.rb +210 -11
  234. data/test/unit/bio/sequence/test_compat.rb +3 -3
  235. data/test/unit/bio/sequence/test_dblink.rb +58 -0
  236. data/test/unit/bio/sequence/test_na.rb +2 -2
  237. data/test/unit/bio/test_command.rb +111 -50
  238. data/test/unit/bio/test_feature.rb +29 -1
  239. data/test/unit/bio/test_location.rb +566 -6
  240. data/test/unit/bio/test_pathway.rb +91 -65
  241. data/test/unit/bio/test_reference.rb +67 -13
  242. data/test/unit/bio/util/restriction_enzyme/analysis/test_calculated_cuts.rb +3 -3
  243. data/test/unit/bio/util/restriction_enzyme/analysis/test_cut_ranges.rb +3 -3
  244. data/test/unit/bio/util/restriction_enzyme/analysis/test_sequence_range.rb +3 -3
  245. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_aligned_strands.rb +4 -3
  246. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_location_pair.rb +3 -3
  247. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_location_pair_in_enzyme_notation.rb +3 -3
  248. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_locations.rb +3 -3
  249. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_locations_in_enzyme_notation.rb +3 -3
  250. data/test/unit/bio/util/restriction_enzyme/single_strand/test_cut_locations_in_enzyme_notation.rb +3 -3
  251. data/test/unit/bio/util/restriction_enzyme/test_analysis.rb +3 -3
  252. data/test/unit/bio/util/restriction_enzyme/test_cut_symbol.rb +4 -4
  253. data/test/unit/bio/util/restriction_enzyme/test_double_stranded.rb +3 -3
  254. data/test/unit/bio/util/restriction_enzyme/test_single_strand.rb +3 -3
  255. data/test/unit/bio/util/restriction_enzyme/test_single_strand_complement.rb +3 -3
  256. data/test/unit/bio/util/restriction_enzyme/test_string_formatting.rb +3 -3
  257. data/test/unit/bio/util/test_restriction_enzyme.rb +3 -3
  258. metadata +202 -167
  259. data/test/unit/bio/appl/blast/test_xmlparser.rb +0 -388
@@ -0,0 +1,32 @@
1
+ #
2
+ # = bio/appl/paml/baseml/report.rb - parser class for PAML program yn00
3
+ #
4
+ # Copyright:: Copyright (C) 2008
5
+ # Naohisa Goto <ng@bioruby.org>
6
+ #
7
+ # License:: The Ruby License
8
+ #
9
+ # == Description
10
+ #
11
+ # This file contains Bio::PAML::Yn00::Report, a parser class for a result
12
+ # of yn00.
13
+ #
14
+ # == References
15
+ #
16
+ # * http://abacus.gene.ucl.ac.uk/software/paml.html
17
+ #
18
+
19
+ require 'bio/appl/paml/yn00'
20
+
21
+ module Bio::PAML
22
+ class Yn00
23
+
24
+ # UNDER CONSTRUCTION.
25
+ #
26
+ # Bio::PAML::Yn00::Report is a parser class for a yn00 result.
27
+ #
28
+ class Report < Bio::PAML::Common::Report
29
+ end #class Report
30
+
31
+ end #class Yn00
32
+ end #module Bio::PAML
@@ -7,7 +7,7 @@ module Bio
7
7
  # Mitsuteru C. Nakao <n@bioruby.org>
8
8
  # License:: The Ruby License
9
9
  #
10
- # $Id: psort.rb,v 1.13 2007/04/05 23:35:39 trevor Exp $
10
+ # $Id:$
11
11
  #
12
12
 
13
13
  require 'bio/appl/psort/report'
@@ -111,7 +111,7 @@ require 'uri'
111
111
  begin
112
112
  result = nil
113
113
  Bio::Command.start_http(@uri.host) {|http|
114
- result, = http.post(@uri.path, data)
114
+ result = http.post(@uri.path, data)
115
115
  }
116
116
  @report = result.body
117
117
  output = parse_report(@report)
@@ -8,7 +8,7 @@ module Bio
8
8
  # Mitsuteru C. Nakao <n@bioruby.org>
9
9
  # License:: The Ruby License
10
10
  #
11
- # $Id: pts1.rb,v 1.5 2007/04/05 23:35:39 trevor Exp $
11
+ # $Id:$
12
12
  #
13
13
 
14
14
  require 'uri'
@@ -116,7 +116,7 @@ class PTS1
116
116
  # serv.function #=> "METAZOA-specific"
117
117
  #
118
118
  def function(func = nil)
119
- return @function.keys.to_s if func == nil
119
+ return @function.keys.join('') if func == nil
120
120
 
121
121
  if FUNCTION.values.include?(func)
122
122
  @function = Hash[*FUNCTION.find {|x| x[1] == func}]
@@ -146,12 +146,12 @@ class PTS1
146
146
  def exec(query)
147
147
  seq = set_sequence_in_fastaformat(query)
148
148
 
149
- @form_data = {'function' => @function.values.to_s,
149
+ @form_data = {'function' => @function.values.join(''),
150
150
  'sequence' => seq.seq,
151
151
  'name' => seq.definition }
152
152
  @uri = URI.parse(["http:/", @host, @cgi_path].join('/'))
153
153
 
154
- result, = Bio::Command.post_form(@uri, @form_data)
154
+ result = Bio::Command.post_form(@uri, @form_data)
155
155
  @output = Report.new(result.body)
156
156
 
157
157
  return @output
@@ -229,7 +229,7 @@ class PTS1
229
229
  private
230
230
 
231
231
  def parse
232
- @output.each do |line|
232
+ @output.each_line do |line|
233
233
  case line
234
234
  when /Name<\/td><td>(\S.+)<\/td><\/tr>/
235
235
  @entry_id = $1
@@ -5,7 +5,7 @@
5
5
  # Mitsuteru C. Nakao <n@bioruby.org>
6
6
  # License:: The Ruby License
7
7
  #
8
- # $Id: report.rb,v 1.8 2007/04/05 23:35:40 trevor Exp $
8
+ # $Id:$
9
9
  #
10
10
  # == Description
11
11
  #
@@ -14,6 +14,8 @@
14
14
  # == References
15
15
  #
16
16
 
17
+ require 'enumerator'
18
+
17
19
  module Bio
18
20
 
19
21
  # = TMHMM class for http://www.cbs.dtu.dk/services/TMHMM/
@@ -81,6 +83,13 @@ module Bio
81
83
 
82
84
  #
83
85
  def initialize(entry = nil)
86
+ begin
87
+ str = entry.to_str
88
+ rescue NoMethodError
89
+ end
90
+ if str then
91
+ entry = str.enum_for(:each_line)
92
+ end
84
93
  parse_header(entry)
85
94
  @tmhs = parse_tmhs(entry)
86
95
  end
@@ -1,18 +1,21 @@
1
1
  #
2
2
  # = bio/command.rb - general methods for external command execution
3
3
  #
4
- # Copyright:: Copyright (C) 2003-2006
4
+ # Copyright:: Copyright (C) 2003-2008
5
5
  # Naohisa Goto <ng@bioruby.org>,
6
6
  # Toshiaki Katayama <k@bioruby.org>
7
7
  # License:: The Ruby License
8
8
  #
9
- # $Id: command.rb,v 1.17 2007/04/05 23:35:39 trevor Exp $
9
+ # $Id:$
10
10
  #
11
11
 
12
12
  require 'open3'
13
13
  require 'uri'
14
14
  require 'open-uri'
15
+ require 'cgi'
15
16
  require 'net/http'
17
+ require 'tmpdir'
18
+ require 'fileutils'
16
19
 
17
20
  module Bio
18
21
 
@@ -32,6 +35,10 @@ module Command
32
35
  module_function
33
36
 
34
37
  # Escape special characters in command line string for cmd.exe on Windows.
38
+ # ---
39
+ # *Arguments*:
40
+ # * (required) _str_: String
41
+ # *Returns*:: String object
35
42
  def escape_shell_windows(str)
36
43
  str = str.to_s
37
44
  raise 'cannot escape control characters' if UNESCAPABLE_CHARS =~ str
@@ -43,6 +50,10 @@ module Command
43
50
  end
44
51
 
45
52
  # Escape special characters in command line string for UNIX shells.
53
+ # ---
54
+ # *Arguments*:
55
+ # * (required) _str_: String
56
+ # *Returns*:: String object
46
57
  def escape_shell_unix(str)
47
58
  str = str.to_s
48
59
  raise 'cannot escape control characters' if UNESCAPABLE_CHARS =~ str
@@ -50,6 +61,10 @@ module Command
50
61
  end
51
62
 
52
63
  # Escape special characters in command line string.
64
+ # ---
65
+ # *Arguments*:
66
+ # * (required) _str_: String
67
+ # *Returns*:: String object
53
68
  def escape_shell(str)
54
69
  case RUBY_PLATFORM
55
70
  when /mswin32|bccwin32/
@@ -60,6 +75,10 @@ module Command
60
75
  end
61
76
 
62
77
  # Generate command line string with special characters escaped.
78
+ # ---
79
+ # *Arguments*:
80
+ # * (required) _ary_: Array containing String objects
81
+ # *Returns*:: String object
63
82
  def make_command_line(ary)
64
83
  case RUBY_PLATFORM
65
84
  when /mswin32|bccwin32/
@@ -71,32 +90,92 @@ module Command
71
90
 
72
91
  # Generate command line string with special characters escaped
73
92
  # for cmd.exe on Windows.
93
+ # ---
94
+ # *Arguments*:
95
+ # * (required) _ary_: Array containing String objects
96
+ # *Returns*:: String object
74
97
  def make_command_line_windows(ary)
75
98
  ary.collect { |str| escape_shell_windows(str) }.join(" ")
76
99
  end
77
100
 
78
101
  # Generate command line string with special characters escaped
79
102
  # for UNIX shells.
103
+ # ---
104
+ # *Arguments*:
105
+ # * (required) _ary_: Array containing String objects
106
+ # *Returns*:: String object
80
107
  def make_command_line_unix(ary)
81
108
  ary.collect { |str| escape_shell_unix(str) }.join(" ")
82
109
  end
83
110
 
111
+ # Returns an Array of command-line command and arguments
112
+ # that can be safely passed to Kernel.exec etc.
113
+ # If the given array is already safe (or empty), returns the given array.
114
+ # ---
115
+ # *Arguments*:
116
+ # * (required) _ary_: Array
117
+ # *Returns*:: Array
118
+ def safe_command_line_array(ary)
119
+ ary = ary.to_ary
120
+ return ary if ary.size >= 2 or ary.empty?
121
+ if ary.size != 1 then
122
+ raise 'Bug: assersion of ary.size == 1 failed'
123
+ end
124
+ arg0 = ary[0]
125
+ begin
126
+ arg0 = arg0.to_ary
127
+ rescue NoMethodError
128
+ arg0 = [ arg0, arg0 ]
129
+ end
130
+ [ arg0 ]
131
+ end
132
+
84
133
  # Executes the program. Automatically select popen for Windows
85
134
  # environment and fork for the others.
86
135
  # A block must be given. An IO object is passed to the block.
87
- def call_command(cmd, &block)
136
+ #
137
+ # Available options:
138
+ # :chdir => "path" : changes working directory to the specified path.
139
+ #
140
+ # ---
141
+ # *Arguments*:
142
+ # * (required) _cmd_: Array containing String objects
143
+ # * (optional) _options_: Hash
144
+ # *Returns*:: (undefined)
145
+ def call_command(cmd, options = {}, &block) #:yields: io
88
146
  case RUBY_PLATFORM
89
147
  when /mswin32|bccwin32/
90
- call_command_popen(cmd, &block)
148
+ call_command_popen(cmd, options, &block)
91
149
  else
92
- call_command_fork(cmd, &block)
150
+ call_command_fork(cmd, options, &block)
93
151
  end
94
152
  end
95
153
 
96
154
  # Executes the program via IO.popen for OS which doesn't support fork.
97
155
  # A block must be given. An IO object is passed to the block.
98
- def call_command_popen(cmd)
156
+ # ---
157
+ # *Arguments*:
158
+ # * (required) _cmd_: Array containing String objects
159
+ # * (optional) _options_: Hash
160
+ # *Returns*:: (undefined)
161
+ def call_command_popen(cmd, options = {})
99
162
  str = make_command_line(cmd)
163
+ # processing options
164
+ if dir = options[:chdir] then
165
+ case RUBY_PLATFORM
166
+ when /mswin32|bccwin32/
167
+ # Unix-like dir separator is changed to Windows dir separator
168
+ # by using String#gsub.
169
+ dirstr = dir.gsub(/\//, "\\")
170
+ chdirstr = make_command_line([ 'cd', '/D', dirstr ])
171
+ str = chdirstr + ' && ' + str
172
+ else
173
+ # UNIX shell
174
+ chdirstr = make_command_line([ 'cd', dir ])
175
+ str = chdirstr + ' && ' + str
176
+ end
177
+ end
178
+ # call command by using IO.popen
100
179
  IO.popen(str, "w+") do |io|
101
180
  io.sync = true
102
181
  yield io
@@ -108,13 +187,28 @@ module Command
108
187
  #
109
188
  # From the view point of security, this method is recommended
110
189
  # rather than call_command_popen.
111
- def call_command_fork(cmd)
190
+ #
191
+ # ---
192
+ # *Arguments*:
193
+ # * (required) _cmd_: Array containing String objects
194
+ # * (optional) _options_: Hash
195
+ # *Returns*:: (undefined)
196
+ def call_command_fork(cmd, options = {})
197
+ dir = options[:chdir]
198
+ cmd = safe_command_line_array(cmd)
112
199
  IO.popen("-", "r+") do |io|
113
200
  if io then
114
201
  # parent
115
202
  yield io
116
203
  else
117
204
  # child
205
+ # chdir to options[:chdir] if available
206
+ begin
207
+ Dir.chdir(dir) if dir
208
+ rescue Exception
209
+ Process.exit!(1)
210
+ end
211
+ # executing the command
118
212
  begin
119
213
  Kernel.exec(*cmd)
120
214
  rescue Errno::ENOENT, Errno::EACCES
@@ -130,8 +224,13 @@ module Command
130
224
  # A block must be given. IO objects are passed to the block.
131
225
  #
132
226
  # You would use this method only when you really need to get stderr.
227
+ #
228
+ # ---
229
+ # *Arguments*:
230
+ # * (required) _cmd_: Array containing String objects
231
+ # *Returns*:: (undefined)
133
232
  def call_command_open3(cmd)
134
- cmd = cmd.collect { |x| x.to_s }
233
+ cmd = safe_command_line_array(cmd)
135
234
  Open3.popen3(*cmd) do |pin, pout, perr|
136
235
  yield pin, pout, perr
137
236
  end
@@ -142,12 +241,22 @@ module Command
142
241
  # standard output as a string.
143
242
  #
144
243
  # Automatically select popen for Windows environment and fork for the others.
145
- def query_command(cmd, query = nil)
244
+ #
245
+ # Available options:
246
+ # :chdir => "path" : changes working directory to the specified path.
247
+ #
248
+ # ---
249
+ # *Arguments*:
250
+ # * (required) _cmd_: Array containing String objects
251
+ # * (optional) _query_: String
252
+ # * (optional) _options_: Hash
253
+ # *Returns*:: String or nil
254
+ def query_command(cmd, query = nil, options = {})
146
255
  case RUBY_PLATFORM
147
256
  when /mswin32|bccwin32/
148
- query_command_popen(cmd, query)
257
+ query_command_popen(cmd, query, options)
149
258
  else
150
- query_command_fork(cmd, query)
259
+ query_command_fork(cmd, query, options)
151
260
  end
152
261
  end
153
262
 
@@ -156,14 +265,22 @@ module Command
156
265
  # standard output as a string.
157
266
  #
158
267
  # IO.popen is used for OS which doesn't support fork.
159
- def query_command_popen(cmd, query = nil)
160
- str = make_command_line(cmd)
161
- IO.popen(str, "w+") do |io|
268
+ #
269
+ # ---
270
+ # *Arguments*:
271
+ # * (required) _cmd_: Array containing String objects
272
+ # * (optional) _query_: String
273
+ # * (optional) _options_: Hash
274
+ # *Returns*:: String or nil
275
+ def query_command_popen(cmd, query = nil, options = {})
276
+ ret = nil
277
+ call_command_popen(cmd, options) do |io|
162
278
  io.sync = true
163
279
  io.print query if query
164
280
  io.close_write
165
- io.read
281
+ ret = io.read
166
282
  end
283
+ ret
167
284
  end
168
285
 
169
286
  # Executes the program with the query (String) given to the standard input,
@@ -173,37 +290,39 @@ module Command
173
290
  # Fork (by using IO.popen("-")) and exec is used to execute the program.
174
291
  #
175
292
  # From the view point of security, this method is recommended
176
- # rather than query_popen.
177
- def query_command_fork(cmd, query = nil)
178
- IO.popen("-", "r+") do |io|
179
- if io then
180
- # parent
181
- io.sync = true
182
- io.print query if query
183
- io.close_write
184
- io.read
185
- else
186
- # child
187
- begin
188
- Kernel.exec(*cmd)
189
- rescue Errno::ENOENT, Errno::EACCES
190
- Process.exit!(127)
191
- rescue Exception
192
- end
193
- Process.exit!(1)
194
- end
293
+ # rather than query_command_popen.
294
+ #
295
+ # ---
296
+ # *Arguments*:
297
+ # * (required) _cmd_: Array containing String objects
298
+ # * (optional) _query_: String
299
+ # * (optional) _options_: Hash
300
+ # *Returns*:: String or nil
301
+ def query_command_fork(cmd, query = nil, options = {})
302
+ ret = nil
303
+ call_command_fork(cmd, options) do |io|
304
+ io.sync = true
305
+ io.print query if query
306
+ io.close_write
307
+ ret = io.read
195
308
  end
309
+ ret
196
310
  end
197
311
 
198
312
  # Executes the program via Open3.popen3 with the query (String) given
199
313
  # to the stain, waits the program termination, and
200
314
  # returns the data from stdout and stderr as an array of the strings.
201
315
  #
202
- # From the view point of security, this method is recommended
203
- # rather than exec_local_popen.
316
+ # You would use this method only when you really need to get stderr.
317
+ #
318
+ # ---
319
+ # *Arguments*:
320
+ # * (required) _cmd_: Array containing String objects
321
+ # * (optional) _query_: String
322
+ # *Returns*:: Array containing 2 objects: output string (or nil) and stderr string (or nil)
204
323
  def query_command_open3(cmd, query = nil)
205
324
  errorlog = nil
206
- cmd = cmd.collect { |x| x.to_s }
325
+ cmd = safe_command_line_array(cmd)
207
326
  Open3.popen3(*cmd) do |pin, pout, perr|
208
327
  perr.sync = true
209
328
  t = Thread.start { errorlog = perr.read }
@@ -218,7 +337,78 @@ module Command
218
337
  end
219
338
  end
220
339
 
221
- # Same as OpenURI.open_uri(uri).read.
340
+ # Same as FileUtils.remove_entry_secure after Ruby 1.8.3.
341
+ # In Ruby 1.8.2 or previous version, it only shows warning message
342
+ # and does nothing.
343
+ #
344
+ # It is strongly recommended using Ruby 1.8.5 or later.
345
+ # ---
346
+ # *Arguments*:
347
+ # * (required) _path_: String
348
+ # * (optional) _force_: boolean
349
+ def remove_entry_secure(path, force = false)
350
+ begin
351
+ FileUtils.remove_entry_secure(path, force)
352
+ rescue NoMethodError
353
+ warn "The temporary file or directory is not removed because of the lack of FileUtils.remove_entry_secure. Use Ruby 1.8.3 or later (1.8.5 or later is strongly recommended): #{path}"
354
+ nil
355
+ end
356
+ end
357
+
358
+ # Backport of Dir.mktmpdir in Ruby 1.9.
359
+ #
360
+ # Same as Dir.mktmpdir(prefix_suffix) in Ruby 1.9 except that
361
+ # prefix must be a String, nil, or omitted.
362
+ #
363
+ # ---
364
+ # *Arguments*:
365
+ # * (optional) _prefix_: String
366
+ #
367
+ def mktmpdir(prefix = 'd', tmpdir = nil, &block)
368
+ prefix = prefix.to_str
369
+ begin
370
+ Dir.mktmpdir(prefix, tmpdir, &block)
371
+ rescue NoMethodError
372
+ suffix = ''
373
+ # backported from Ruby 1.9.0.
374
+ # ***** Below is excerpted from Ruby 1.9.0's lib/tmpdir.rb ****
375
+ # ***** Be careful about copyright. ****
376
+ tmpdir ||= Dir.tmpdir
377
+ t = Time.now.strftime("%Y%m%d")
378
+ n = nil
379
+ begin
380
+ path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
381
+ path << "-#{n}" if n
382
+ path << suffix
383
+ Dir.mkdir(path, 0700)
384
+ rescue Errno::EEXIST
385
+ n ||= 0
386
+ n += 1
387
+ retry
388
+ end
389
+
390
+ if block_given?
391
+ begin
392
+ yield path
393
+ ensure
394
+ remove_entry_secure path
395
+ end
396
+ else
397
+ path
398
+ end
399
+ # ***** Above is excerpted from Ruby 1.9.0's lib/tmpdir.rb ****
400
+ end
401
+ end
402
+
403
+ # Same as OpenURI.open_uri(uri).read
404
+ # and
405
+ # it uses proxy if an environment variable (same as OpenURI.open_uri)
406
+ # is set.
407
+ #
408
+ # ---
409
+ # *Arguments*:
410
+ # * (required) _uri_: URI object or String
411
+ # *Returns*:: String
222
412
  def read_uri(uri)
223
413
  OpenURI.open_uri(uri).read
224
414
  end
@@ -229,6 +419,11 @@ module Command
229
419
  # it uses proxy if an environment variable (same as OpenURI.open_uri)
230
420
  # is set.
231
421
  #
422
+ # ---
423
+ # *Arguments*:
424
+ # * (required) _address_: String containing host name or IP address
425
+ # * (optional) _port_: port (sanme as Net::HTTP::start)
426
+ # *Returns*:: (same as Net::HTTP::start except for proxy support)
232
427
  def start_http(address, port = 80, &block)
233
428
  uri = URI.parse("http://#{address}:#{port}")
234
429
  # Note: URI#find_proxy is an unofficial method defined in open-uri.rb.
@@ -248,6 +443,11 @@ module Command
248
443
  # it uses proxy if an environment variable (same as OpenURI.open_uri)
249
444
  # is set.
250
445
  #
446
+ # ---
447
+ # *Arguments*:
448
+ # * (required) _address_: String containing host name or IP address
449
+ # * (optional) _port_: port (sanme as Net::HTTP::start)
450
+ # *Returns*:: (same as Net::HTTP.new except for proxy support)
251
451
  def new_http(address, port = 80)
252
452
  uri = URI.parse("http://#{address}:#{port}")
253
453
  # Note: URI#find_proxy is an unofficial method defined in open-uri.rb.
@@ -260,6 +460,36 @@ module Command
260
460
  end
261
461
  end
262
462
 
463
+ # Same as:
464
+ # http = Net::HTTP.new(...); http.post_form(path, params)
465
+ # and
466
+ # it uses proxy if an environment variable (same as OpenURI.open_uri)
467
+ # is set.
468
+ # In addition, +header+ can be set.
469
+ # (Note that Content-Type and Content-Length are automatically
470
+ # set by default.)
471
+ # +uri+ must be a URI object, +params+ must be a hash, and
472
+ # +header+ must be a hash.
473
+ #
474
+ # ---
475
+ # *Arguments*:
476
+ # * (required) _http_: Net::HTTP object or compatible object
477
+ # * (required) _path_: String
478
+ # * (optional) _params_: Hash containing parameters
479
+ # * (optional) _header_: Hash containing header strings
480
+ # *Returns*:: (same as Net::HTTP::post_form)
481
+ def http_post_form(http, path, params = nil, header = {})
482
+ data = make_cgi_params(params)
483
+
484
+ hash = {
485
+ 'Content-Type' => 'application/x-www-form-urlencoded',
486
+ 'Content-Length' => data.length.to_s
487
+ }
488
+ hash.update(header)
489
+
490
+ http.post(path, data, hash)
491
+ end
492
+
263
493
  # Same as:
264
494
  # Net::HTTP.post_form(uri, params)
265
495
  # and
@@ -271,6 +501,12 @@ module Command
271
501
  # +uri+ must be a URI object, +params+ must be a hash, and
272
502
  # +header+ must be a hash.
273
503
  #
504
+ # ---
505
+ # *Arguments*:
506
+ # * (required) _uri_: URI object or String
507
+ # * (optional) _params_: Hash containing parameters
508
+ # * (optional) _header_: Hash containing header strings
509
+ # *Returns*:: (same as Net::HTTP::post_form)
274
510
  def post_form(uri, params = nil, header = {})
275
511
  unless uri.is_a?(URI)
276
512
  uri = URI.parse(uri)
@@ -289,6 +525,13 @@ module Command
289
525
  end
290
526
  end
291
527
 
528
+ # Builds parameter string for from Hash of parameters for
529
+ # application/x-www-form-urlencoded.
530
+ #
531
+ # ---
532
+ # *Arguments*:
533
+ # * (required) _params_: Hash containing parameters
534
+ # *Returns*:: String
292
535
  def make_cgi_params(params)
293
536
  data = ""
294
537
  case params
@@ -310,7 +553,12 @@ module Command
310
553
  end.join('&')
311
554
  when String
312
555
  data = params.map do |str|
313
- URI.escape(str.strip)
556
+ key, val = str.split(/\=/, 2)
557
+ if val then
558
+ make_cgi_params_key_value(key, val)
559
+ else
560
+ CGI.escape(str)
561
+ end
314
562
  end.join('&')
315
563
  end
316
564
  when String
@@ -319,15 +567,23 @@ module Command
319
567
  return data
320
568
  end
321
569
 
570
+ # Builds parameter string for from a key string and a value (or values)
571
+ # for application/x-www-form-urlencoded.
572
+ #
573
+ # ---
574
+ # *Arguments*:
575
+ # * (required) _key_: String
576
+ # * (required) _value_: String or Array containing String
577
+ # *Returns*:: String
322
578
  def make_cgi_params_key_value(key, value)
323
579
  result = []
324
580
  case value
325
581
  when Array
326
582
  value.each do |val|
327
- result << [key, val].map {|x| URI.escape(x.to_s) }.join('=')
583
+ result << [key, val].map {|x| CGI.escape(x.to_s) }.join('=')
328
584
  end
329
585
  else
330
- result << [key, value].map {|x| URI.escape(x.to_s) }.join('=')
586
+ result << [key, value].map {|x| CGI.escape(x.to_s) }.join('=')
331
587
  end
332
588
  return result
333
589
  end