tap-tasks 0.5.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/History CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.7.0 / 2010-05-02
2
+
3
+ Updates for Tap-1.3.0
4
+
1
5
  == 0.5.0 / 2009-12-05
2
6
 
3
7
  Updates for Tap-0.19.0
@@ -1,6 +1,6 @@
1
1
  Copyright (c) 2009, Regents of the University of Colorado.
2
2
 
3
- Copyright (c) 2009, Simon Chiang.
3
+ Copyright (c) 2009-2010, Simon Chiang.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README CHANGED
@@ -7,9 +7,7 @@ A set of standard Tap tasks.
7
7
  == Description
8
8
 
9
9
  A standard library of utility tasks, for example tasks to dump/load results as
10
- {YAML}[http://www.yaml.org/]. {Tap-Tasks}[http://tap.rubyforge.org/tap-tasks]
11
- is a part of the {Tap-Suite}[http://tap.rubyforge.org/tap-suite]. Check out
12
- these links for documentation, development, and bug tracking.
10
+ {YAML}[http://www.yaml.org/] or CSV.
13
11
 
14
12
  * Website[http://tap.rubyforge.org]
15
13
  * Github[http://github.com/bahuvrihi/tap/tree/master]
@@ -19,7 +17,7 @@ these links for documentation, development, and bug tracking.
19
17
 
20
18
  Usage is the same as for any tasks.
21
19
 
22
- % tap run -- load/yaml "{key: value}" --: inspect
20
+ % tap load/yaml "{key: value}" -: inspect
23
21
  {"key" => "value"}
24
22
 
25
23
  == Installation
@@ -0,0 +1,43 @@
1
+ require 'tap/task'
2
+ require 'tap/declarations'
3
+ require 'irb'
4
+
5
+ # http://www.ruby-forum.com/topic/182335
6
+ class IRB::Irb
7
+ alias initialize_orig initialize
8
+ def initialize(workspace = nil, *args)
9
+ default = IRB.conf[:DEFAULT_OBJECT]
10
+ workspace ||= IRB::WorkSpace.new(default) if default
11
+ initialize_orig(workspace, *args)
12
+ end
13
+ end
14
+
15
+ module Tap
16
+ module Tasks
17
+ # :startdoc::task start an irb session
18
+ #
19
+ # Console allows interaction with tap via IRB. Starts an IRB sssion with
20
+ # the same context as a tapfile (a Tap::Declarations::Context). Only one
21
+ # console can be running at time.
22
+ #
23
+ class Console < Tap::Task
24
+ # Handles a bug in IRB that causes exit to throw :IRB_EXIT
25
+ # and consequentially make a warning message, even on a
26
+ # clean exit. This module resets exit to the original
27
+ # aliased method.
28
+ module CleanExit # :nodoc:
29
+ def exit(ret = 0)
30
+ __exit__(ret)
31
+ end
32
+ end
33
+
34
+ def process
35
+ raise "console already running" if IRB.conf[:DEFAULT_OBJECT]
36
+ IRB.conf[:DEFAULT_OBJECT] = Declarations::Context.new(app, "console")
37
+ IRB.start
38
+ IRB.conf[:DEFAULT_OBJECT] = nil
39
+ IRB.CurrentContext.extend CleanExit
40
+ end
41
+ end
42
+ end
43
+ end
@@ -11,18 +11,28 @@ module Tap
11
11
  # into a single line of csv, ie multiple dumps build the csv results.
12
12
  # Non-array objects are converted to arrays using to_ary.
13
13
  #
14
- # % tap run -- load/yaml ["a", "b", "c"] --: dump/csv
14
+ # % tap load/yaml '["a", "b", "c"]' -: dump/csv
15
15
  # a,b,c
16
16
  #
17
17
  class Csv < Dump
18
18
 
19
19
  config :col_sep, ",", :short => :c, &c.string # The column separator (",")
20
- config :row_sep, "\n", :short => :r, &c.string # The row separator ("\n")
20
+ config :row_sep, $/, :short => :r, &c.string # The row separator ("\n")
21
21
 
22
- # Dumps the data to io as CSV. Data is converted to an array using
23
- # to_ary.
24
22
  def dump(data, io)
25
- io << CSV.generate_line(data.to_ary, col_sep) + row_sep
23
+ io << generate_line(data.to_ary)
24
+ end
25
+
26
+ private
27
+
28
+ if RUBY_VERSION >= '1.9'
29
+ def generate_line(data)
30
+ CSV.generate_line(data, :col_sep => col_sep, :row_sep => row_sep)
31
+ end
32
+ else
33
+ def generate_line(data)
34
+ CSV.generate_line(data, col_sep) + row_sep
35
+ end
26
36
  end
27
37
  end
28
38
  end
@@ -10,15 +10,12 @@ module Tap
10
10
  # method can be specified for inspection using the inspect_method
11
11
  # config.
12
12
  #
13
- # % tap run -- load/yaml "{key: value}" --: inspect
13
+ # % tap load/yaml "{key: value}" -: inspect
14
14
  # {"key"=>"value"}
15
15
  #
16
- # % tap run -- load string --: inspect -m length
17
- # 6
18
- #
19
16
  class Inspect < Dump
20
17
 
21
- config :inspect_method, 'inspect', :short => :m # The inspection method
18
+ config :inspect_method, 'inspect', :long => :method, :short => :m # The inspection method
22
19
 
23
20
  # Dumps the object to io using obj.inspect
24
21
  def dump(obj, io)
@@ -8,7 +8,7 @@ module Tap
8
8
  #
9
9
  # Dumps workflow results to a file or IO as YAML.
10
10
  #
11
- # % tap run -- load/yaml "{key: value}" --: dump/yaml
11
+ # % tap load/yaml "{key: value}" -: dump/yaml
12
12
  # ---
13
13
  # key: value
14
14
  #
@@ -0,0 +1,16 @@
1
+ require 'tap/task'
2
+
3
+ module Tap
4
+ module Tasks
5
+ # :startdoc::task raises an error
6
+ #
7
+ # Error raises a Runtime error when called. The input specifies the
8
+ # error message.
9
+ #
10
+ class Error < Tap::Task
11
+ def process(msg=nil)
12
+ raise msg
13
+ end
14
+ end
15
+ end
16
+ end
@@ -7,7 +7,7 @@ module Tap
7
7
  # Globs the input patterns for matching patterns. Matching files are
8
8
  # returned as an array.
9
9
  #
10
- # % tap run -- glob * --: dump/yaml
10
+ # % tap glob * -: dump/yaml
11
11
  #
12
12
  # A variety of filters are available as configurations.
13
13
  #
@@ -20,7 +20,7 @@ module Tap
20
20
  #
21
21
  # To glob within the task and not the command line, quote the glob.
22
22
  #
23
- # % tap run -- glob '*' --: dump/yaml
23
+ # % tap glob '*' -: dump/yaml
24
24
  #
25
25
  class Glob < Tap::Task
26
26
 
@@ -0,0 +1,89 @@
1
+ require 'tap/task'
2
+
3
+ module Tap
4
+ module Tasks
5
+ # :startdoc::task insert into an array
6
+ #
7
+ # Insert supports a common workflow pattern of inserting variable
8
+ # arguments into an otherwise static array.
9
+ #
10
+ # % tap load moon -: insert goodnight %0 -: inspect
11
+ # ["goodnight", "moon"]
12
+ #
13
+ # The percent serves as a placeholder identifying the index of the
14
+ # argument that will be inserted. Unlike most tasks, command-line
15
+ # arguments provided to insert define the insertion template rather than
16
+ # inputs (ie they cannot be enqued or executed with -- or -!) so typically
17
+ # inserts are used with joins or signals.
18
+ #
19
+ # % tap insert goodnight %0 -: inspect -/enq 0 moon
20
+ # ["goodnight", "moon"]
21
+ #
22
+ # Arguments can be used more than once, as indicated. The default value
23
+ # will be used if the argument value at the given index is nil.
24
+ #
25
+ # % tap load a -: insert %0 %0 %1 -: inspect
26
+ # ["a", "a", nil]
27
+ #
28
+ class Insert < Tap::Task
29
+ class << self
30
+ def parse(argv=ARGV, app=Tap::App.current)
31
+ super(argv, app, &nil)
32
+ end
33
+
34
+ def parse!(argv=ARGV, app=Tap::App.current)
35
+ super(argv, app, &nil)
36
+ end
37
+
38
+ def build(spec={}, app=Tap::App.current)
39
+ new(spec['template'], spec['config'], app)
40
+ end
41
+
42
+ def convert_to_spec(parser, args)
43
+ template = args.dup
44
+ args.clear
45
+
46
+ {
47
+ 'config' => parser.nested_config,
48
+ 'template' => template
49
+ }
50
+ end
51
+ end
52
+
53
+ config :placeholder, '%', :short => :p, &c.string # argument placeholder
54
+ config :default, nil # default insert value
55
+
56
+ attr_reader :template
57
+
58
+ def initialize(template, config={}, app=Tap::App.current)
59
+ super(config, app)
60
+ @template = template
61
+ @map = {}
62
+
63
+ plength = placeholder.length
64
+ template.each_with_index do |arg, index|
65
+ if arg.index(placeholder) == 0
66
+ @map[index] = arg[plength, arg.length - plength].to_i
67
+ end
68
+ end
69
+ end
70
+
71
+ def process(*args)
72
+ result = template.dup
73
+
74
+ @map.each_pair do |insert_idx, arg_idx|
75
+ value = args[arg_idx]
76
+ result[insert_idx] = value.nil? ? default : value
77
+ end
78
+
79
+ result
80
+ end
81
+
82
+ def to_spec
83
+ spec = super
84
+ spec['template'] = template
85
+ spec
86
+ end
87
+ end
88
+ end
89
+ end
@@ -10,7 +10,7 @@ module Tap
10
10
  # Load CSV data as an array of arrays, selecting the specified rows and
11
11
  # columns.
12
12
  #
13
- # % tap run -- load/csv 'a,b,c.d,e,f' --row-sep '.' --: inspect
13
+ # % tap load/csv 'a,b,c.d,e,f' --row-sep '.' -: inspect
14
14
  # [["a", "b", "c"], ["d", "e", "f"]]
15
15
  #
16
16
  # Note this task is quite inefficient in that it will load all data
@@ -22,12 +22,12 @@ module Tap
22
22
  config :columns, nil, :short => :C, &c.range_or_nil # Specify a range of columns
23
23
  config :rows, nil, :short => :R, &c.range_or_nil # Specify a range of rows
24
24
 
25
- config :col_sep, nil, :short => :c, &c.string_or_nil # The column separator (",")
26
- config :row_sep, nil, :short => :r, &c.string_or_nil # The row separator ("\r\n" or "\n")
25
+ config :col_sep, ',', :short => :c, &c.string_or_nil # The column separator (",")
26
+ config :row_sep, $/, :short => :r, &c.string_or_nil # The row separator ("\r\n" or "\n")
27
27
 
28
28
  # Loads the io data as CSV, into an array of arrays.
29
29
  def load(io)
30
- data = CSV.parse(io.read, col_sep, row_sep)
30
+ data = parse(io.read)
31
31
 
32
32
  if rows
33
33
  data = data[rows]
@@ -42,6 +42,17 @@ module Tap
42
42
  data
43
43
  end
44
44
 
45
+ private
46
+
47
+ if RUBY_VERSION >= '1.9'
48
+ def parse(str)
49
+ CSV.parse(str, :col_sep => col_sep, :row_sep => row_sep)
50
+ end
51
+ else
52
+ def parse(str)
53
+ CSV.parse(str, col_sep, row_sep)
54
+ end
55
+ end
45
56
  end
46
57
  end
47
58
  end
@@ -8,7 +8,7 @@ module Tap
8
8
  #
9
9
  # Loads data from the input IO as YAML.
10
10
  #
11
- # % tap run -- load/yaml "{key: value}" --: dump/yaml
11
+ # % tap load/yaml "{key: value}" --: dump/yaml
12
12
  # ---
13
13
  # key: value
14
14
  #
@@ -8,11 +8,10 @@ module Tap
8
8
  # to Null go nowhere. Null does not accept joins and will not execute
9
9
  # the default app joins.
10
10
  #
11
- # % tap run -- load a --: null
11
+ # % tap load/yaml '[1, 2, 3]' -: null
12
12
  #
13
- class Null < Tap::Task
13
+ class Null < Tap::Task
14
14
  def process(*args)
15
- nil
16
15
  end
17
16
 
18
17
  def joins
@@ -0,0 +1,17 @@
1
+ require 'tap/task'
2
+
3
+ module Tap
4
+ module Tasks
5
+ # :startdoc::task sleep
6
+ #
7
+ # Sleeps for the specified duration.
8
+ class Sleep < Tap::Task
9
+ config :duration, 1, &c.numeric # sleep duration (ms)
10
+
11
+ def call(input)
12
+ sleep duration
13
+ super
14
+ end
15
+ end
16
+ end
17
+ end
@@ -18,7 +18,7 @@ module Tap
18
18
  # ---
19
19
  # key: value
20
20
  #
21
- # % tap run -- stream/yaml --file example.yml --: inspect
21
+ # % tap stream/yaml --file example.yml -: inspect
22
22
  # :sym
23
23
  # [1, 2, 3]
24
24
  # {"key"=>"value"}
@@ -1,7 +1,7 @@
1
1
  module Tap
2
2
  module Tasks
3
3
  MAJOR = 0
4
- MINOR = 5
4
+ MINOR = 7
5
5
  TINY = 0
6
6
 
7
7
  VERSION="#{MAJOR}.#{MINOR}.#{TINY}"
@@ -0,0 +1,50 @@
1
+ $:.unshift File.expand_path('../../tap/lib', __FILE__)
2
+ $:.unshift File.expand_path('../../tap-test/lib', __FILE__)
3
+ $:.unshift File.expand_path('../../tap-tasks/lib', __FILE__)
4
+
5
+ require 'tap/version'
6
+ require 'tap/test/version'
7
+ require 'tap/tasks/version'
8
+
9
+ Gem::Specification.new do |s|
10
+ s.name = 'tap-tasks'
11
+ s.version = Tap::Tasks::VERSION
12
+ s.author = 'Simon Chiang'
13
+ s.email = 'simon.a.chiang@gmail.com'
14
+ s.homepage = File.join(Tap::WEBSITE, 'tap-tasks')
15
+ s.platform = Gem::Platform::RUBY
16
+ s.summary = 'A set of standard Tap tasks'
17
+ s.require_path = 'lib'
18
+ s.rubyforge_project = 'tap'
19
+ s.add_dependency('tap', ">= #{Tap::VERSION}")
20
+ s.add_development_dependency('tap-test', ">= #{Tap::Test::VERSION}")
21
+ s.has_rdoc = true
22
+ s.rdoc_options.concat %W{--main README -S -N --title Tap-Tasks}
23
+
24
+ # list extra rdoc files here.
25
+ s.extra_rdoc_files = %W{
26
+ History
27
+ README
28
+ MIT-LICENSE
29
+ }
30
+
31
+ # list the files you want to include here. you can
32
+ # check this manifest using 'rap print_manifest'
33
+ s.files = %W{
34
+ lib/tap/tasks/insert.rb
35
+ lib/tap/tasks/console.rb
36
+ lib/tap/tasks/dump/csv.rb
37
+ lib/tap/tasks/dump/inspect.rb
38
+ lib/tap/tasks/dump/yaml.rb
39
+ lib/tap/tasks/error.rb
40
+ lib/tap/tasks/glob.rb
41
+ lib/tap/tasks/load/csv.rb
42
+ lib/tap/tasks/load/yaml.rb
43
+ lib/tap/tasks/null.rb
44
+ lib/tap/tasks/sleep.rb
45
+ lib/tap/tasks/stream/yaml.rb
46
+ lib/tap/tasks/version.rb
47
+ tap-tasks.gemspec
48
+ tap.yml
49
+ }
50
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tap-tasks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 7
8
+ - 0
9
+ version: 0.7.0
5
10
  platform: ruby
6
11
  authors:
7
12
  - Simon Chiang
@@ -9,29 +14,37 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2009-12-05 00:00:00 -07:00
17
+ date: 2010-05-02 00:00:00 -06:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: tap
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
23
- version: 0.19.0
24
- version:
27
+ segments:
28
+ - 1
29
+ - 3
30
+ - 0
31
+ version: 1.3.0
32
+ type: :runtime
33
+ version_requirements: *id001
25
34
  - !ruby/object:Gem::Dependency
26
35
  name: tap-test
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
30
38
  requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
33
- version: 0.3.0
34
- version:
41
+ segments:
42
+ - 0
43
+ - 6
44
+ - 0
45
+ version: 0.6.0
46
+ type: :development
47
+ version_requirements: *id002
35
48
  description:
36
49
  email: simon.a.chiang@gmail.com
37
50
  executables: []
@@ -43,24 +56,26 @@ extra_rdoc_files:
43
56
  - README
44
57
  - MIT-LICENSE
45
58
  files:
46
- - lib/tap/joins/gate.rb
47
- - lib/tap/middlewares/profiler.rb
59
+ - lib/tap/tasks/insert.rb
60
+ - lib/tap/tasks/console.rb
48
61
  - lib/tap/tasks/dump/csv.rb
49
62
  - lib/tap/tasks/dump/inspect.rb
50
63
  - lib/tap/tasks/dump/yaml.rb
51
- - lib/tap/tasks/load/yaml.rb
64
+ - lib/tap/tasks/error.rb
65
+ - lib/tap/tasks/glob.rb
52
66
  - lib/tap/tasks/load/csv.rb
67
+ - lib/tap/tasks/load/yaml.rb
53
68
  - lib/tap/tasks/null.rb
54
- - lib/tap/tasks/glob.rb
55
- - lib/tap/tasks/stream.rb
69
+ - lib/tap/tasks/sleep.rb
56
70
  - lib/tap/tasks/stream/yaml.rb
57
71
  - lib/tap/tasks/version.rb
72
+ - tap-tasks.gemspec
58
73
  - tap.yml
59
74
  - History
60
75
  - README
61
76
  - MIT-LICENSE
62
77
  has_rdoc: true
63
- homepage: http://tap.rubyforge.org/tap-tasks/
78
+ homepage: http://tap.rubyforge.org/tap-tasks
64
79
  licenses: []
65
80
 
66
81
  post_install_message:
@@ -77,18 +92,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
92
  requirements:
78
93
  - - ">="
79
94
  - !ruby/object:Gem::Version
95
+ segments:
96
+ - 0
80
97
  version: "0"
81
- version:
82
98
  required_rubygems_version: !ruby/object:Gem::Requirement
83
99
  requirements:
84
100
  - - ">="
85
101
  - !ruby/object:Gem::Version
102
+ segments:
103
+ - 0
86
104
  version: "0"
87
- version:
88
105
  requirements: []
89
106
 
90
107
  rubyforge_project: tap
91
- rubygems_version: 1.3.5
108
+ rubygems_version: 1.3.6
92
109
  signing_key:
93
110
  specification_version: 3
94
111
  summary: A set of standard Tap tasks
@@ -1,87 +0,0 @@
1
- require 'tap/join'
2
-
3
- module Tap
4
- module Joins
5
-
6
- # :startdoc::join collects results before the join
7
- #
8
- # Similar to a synchronized merge, but collects all results regardless of
9
- # where they come from. Gates enque themselves when called as a join, and
10
- # won't let results pass until they get run as a node.
11
- #
12
- # % tap run -- load a -- load b -- inspect --[0,1][2].gate
13
- # ["a", "b"]
14
- #
15
- # Gates are useful in conjunction with iteration where a single task may
16
- # feed multiple results to a single join; in this case a sync merge doesn't
17
- # produce the desired behavior of collecting the results.
18
- #
19
- # % tap run -- load/yaml "[1, 2, 3]" --:i inspect --:.gate inspect
20
- # 1
21
- # 2
22
- # 3
23
- # [1, 2, 3]
24
- #
25
- # % tap run -- load/yaml "[1, 2, 3]" --:i inspect --:.sync inspect
26
- # 1
27
- # [1]
28
- # 2
29
- # [2]
30
- # 3
31
- # [3]
32
- #
33
- # When a limit is specified, the gate will collect results up to the limit
34
- # and then pass the results. Any leftover results are still passed at the
35
- # end.
36
- #
37
- # % tap run -- load/yaml "[1, 2, 3]" --:i inspect -- inspect --. gate 1 2 --limit 2
38
- # 1
39
- # 2
40
- # [1, 2]
41
- # 3
42
- # [3]
43
- #
44
- class Gate < Join
45
-
46
- # An array of results collected thusfar.
47
- attr_reader :results
48
-
49
- config :limit, nil, :short => :l, &c.integer_or_nil # Pass results after limit
50
-
51
- def initialize(config={}, app=Tap::App.instance)
52
- super
53
- @results = nil
54
- end
55
-
56
- def call(result)
57
- if @results
58
- # Results are set, so self is already enqued and collecting
59
- # results. If the input is the collection, then it's time
60
- # to dispatch the results and reset. Otherwise, just
61
- # collect the input and wait.
62
-
63
- if result == @results
64
- @results = nil
65
- super(result)
66
- else
67
- @results << result
68
-
69
- if limit && @results.length >= limit
70
- super(@results.dup)
71
- @results.clear
72
- end
73
- end
74
-
75
- else
76
- # No results are set, so this is a first call and self is
77
- # not enqued. Setup the collection.
78
-
79
- @results = [result]
80
- app.enq(self, @results)
81
- end
82
-
83
- self
84
- end
85
- end
86
- end
87
- end
@@ -1,72 +0,0 @@
1
- require 'tap/middleware'
2
-
3
- module Tap
4
- module Middlewares
5
-
6
- # :startdoc::middleware profile the workflow execution time
7
- #
8
- #
9
- class Profiler < Tap::Middleware
10
-
11
- attr_reader :app_time
12
- attr_reader :nodes
13
- attr_reader :counts
14
-
15
- def initialize(stack, config={})
16
- super
17
- reset
18
- at_exit { app.quiet = false; app.log(:profile, "\n" + summary.join("\n")) }
19
- end
20
-
21
- def reset
22
- @app_time = 0
23
- @last = nil
24
- @nodes = Hash.new(0)
25
- @counts = Hash.new(0)
26
- end
27
-
28
- def total_time
29
- nodes.values.inject(0) {|sum, elapsed| sum + elapsed }
30
- end
31
-
32
- def total_counts
33
- counts.values.inject(0) {|sum, n| sum + n }
34
- end
35
-
36
- def call(node, inputs=[])
37
- @app_time += Time.now - @last if @last
38
-
39
- start = Time.now
40
- result = super
41
- elapsed = Time.now - start
42
-
43
- nodes[node] += elapsed
44
- counts[node] += 1
45
-
46
- @last = Time.now
47
- result
48
- end
49
-
50
- def summary
51
- lines = []
52
- lines << "App Time: #{app_time}s"
53
- lines << "Node Time: #{total_time}s"
54
- lines << "Nodes Run: #{total_counts}"
55
- lines << "Breakdown:"
56
-
57
- nodes_by_class = {}
58
- nodes.each_key do |node|
59
- (nodes_by_class[node.class.to_s] ||= []) << node
60
- end
61
-
62
- nodes_by_class.keys.sort.each do |node_class|
63
- nodes_by_class[node_class].each do |node|
64
- lines << "- #{node_class}: [#{nodes[node]}, #{counts[node]}]"
65
- end
66
- end
67
-
68
- lines
69
- end
70
- end
71
- end
72
- end
@@ -1,64 +0,0 @@
1
- require 'tap/tasks/load'
2
-
3
- module Tap
4
- module Tasks
5
-
6
- # Stream recurrently loads data from $stdin by requeing self until an
7
- # end-of-file is reached. This behavior is useful for creating tasks
8
- # that load a bit of data from an IO, send it into a workflow, and then
9
- # repeat.
10
- #
11
- # The eof cutoff can be modified using complete? method. Streaming will
12
- # stop when complete? returns true. For instance, this is a prompt task:
13
- #
14
- # class Prompt < Tap::Tasks::Stream
15
- # config :exit_seq, "\n"
16
- #
17
- # def load(io)
18
- # if io.eof?
19
- # nil
20
- # else
21
- # io.readline
22
- # end
23
- # end
24
- #
25
- # def complete?(io, line)
26
- # line == nil || line == exit_seq
27
- # end
28
- # end
29
- #
30
- class Stream < Load
31
-
32
- # Loads data from io. Process will open the input io object, load
33
- # a result, then check to see if the loading is complete (using the
34
- # complete? method). Unless loading is complete, process will enque
35
- # io to self. Process will close io when loading is complete, provided
36
- # use_close or file is specified.
37
- def process(io=$stdin)
38
- io = open(io)
39
- result = load(io)
40
-
41
- if complete?(io, result)
42
- if use_close || file
43
- close(io)
44
- end
45
- else
46
- reque(io)
47
- end
48
-
49
- result
50
- end
51
-
52
- # Returns true by default. Override in subclasses to allow recurrent
53
- # loading (see process).
54
- def complete?(io, last)
55
- io.eof?
56
- end
57
-
58
- # Reques self with io to the top of the queue.
59
- def reque(io)
60
- app.queue.unshift(self, [io])
61
- end
62
- end
63
- end
64
- end