ing 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,98 @@
1
+ require 'rake-pipeline'
2
+
3
+ # This is Rake::Pipeline::CLI rewritten as an Ing task
4
+ # instead of Thor
5
+ # cf. https://github.com/livingsocial/rake-pipeline
6
+ #
7
+ # Stick this in your ing.rb and you can simply run
8
+ #
9
+ # ing pipeline:build
10
+ #
11
+ # to build your project, or
12
+ #
13
+ # ing pipeline
14
+ #
15
+ # to start the preview server (equivalent to +rakep+)
16
+ #
17
+ module Pipeline
18
+
19
+ # default == server
20
+ def self.call(*args)
21
+ Ing.execute Server, *args
22
+ end
23
+
24
+ module Helpers
25
+
26
+ private
27
+
28
+ def project
29
+ @project ||= Rake::Pipeline::Project.new(options[:assetfile])
30
+ end
31
+
32
+ # @param [FileWrapper|String] path
33
+ # @return [String] The path to the file with the current
34
+ # directory stripped out.
35
+ def relative_path(path)
36
+ pathstr = path.respond_to?(:fullpath) ? path.fullpath : path
37
+ pathstr.sub(%r|#{Dir.pwd}/|, '')
38
+ end
39
+
40
+ end
41
+
42
+ class Build < Ing::Task
43
+ include Helpers
44
+
45
+ desc "Build the project."
46
+ usage " ing pipeline build"
47
+ opt :assetfile, "Asset file", :default => "Assetfile", :short => "c"
48
+ opt :pretend
49
+ opt :clean, "Clean before building"
50
+
51
+ # ing pipeline build
52
+ def call
53
+ if options[:pretend]
54
+ project.output_files.each do |file|
55
+ shell.say_status :create, relative_path(file)
56
+ end
57
+ else
58
+ options[:clean] ? Ing.invoke(Clean, options) : project.cleanup_tmpdir
59
+ project.invoke
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ class Clean < Ing::Task
66
+ include Helpers
67
+
68
+ desc "Remove the pipeline's temporary and output files."
69
+ usage " ing pipeline clean"
70
+ opt :pretend
71
+
72
+ # ing pipeline clean
73
+ def call
74
+ if options[:pretend]
75
+ project.files_to_clean.each do |file|
76
+ shell.say_status :remove, relative_path(file)
77
+ end
78
+ else
79
+ project.clean
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ class Server < Ing::Task
86
+
87
+ desc "Run the Rake::Pipeline preview server (default task)."
88
+ usage " ing pipeline server"
89
+
90
+ # ing pipeline server
91
+ def call
92
+ require "rake-pipeline/server"
93
+ Rake::Pipeline::Server.new.start
94
+ end
95
+
96
+ end
97
+
98
+ end
data/ing.rb CHANGED
@@ -1,102 +1,2 @@
1
- # Usage:
2
- # ing rspec:convert which is equivalent to
3
- # ing rspec:convert files './{test,spec}/**/*.rb' --convert-dir 'converted'
4
- #
5
- module Rspec
6
-
7
- class Convert
8
-
9
- GSUBS = \
10
- [
11
- [ /^(\s*)(.+)\.should\s+be_true/ , '\1assert \2' ],
12
- [ /^(\s*)(.+)\.should\s+be_false/ , '\1refute \2' ],
13
- [ /^(\s*)(.+)\.should\s*==\s*(.+)$/ , '\1assert_equal \3, \2' ],
14
- [ /^(\s*)(.+)\.should_not\s*==\s*(.+)$/ , '\1refute_equal \3, \2' ],
15
- [ /^(\s*)(.+)\.should\s*=~\s*(.+)$/ , '\1assert_match(\3, \2)' ],
16
- [ /^(\s*)(.+)\.should_not\s*=~\s*(.+)$/ , '\1refute_match(\3, \2)' ],
17
- [ /^(\s*)(.+)\.should\s+be_(.+)$/ , '\1assert \2.\3?' ],
18
- [ /^(\s*)(.+)\.should_not\s+be_(.+)$/ , '\1refute \2.\3?' ],
19
- [ /expect\s+\{(.+)\}\.to\s+raise_error\s*\((.*)\)\s*\Z/m,
20
- 'assert_raises(\2) {\1}' ],
21
- [ /\{(.+)\}\.should raise_error\s*\((.*)\)\s*\Z/m,
22
- 'assert_raises(\2) {\1}' ],
23
- # these next aren't quite right because they need to wrap the next
24
- # lines as a lambda. Thus the FIXME notes.
25
- [ /\.should_receive\(([^\)]+)\)\.and_return\((.+)\)/,
26
- '.stub(\1, \2) do |s| # FIXME' ],
27
- [ /.stub\!\(([\w:]+)\)\.and_return\((.+)\)/,
28
- '.stub(\1, \2) do |s| # FIXME' ]
29
-
30
- ]
31
-
32
- def self.specify_options(expect)
33
- expect.banner "Convert rspec 'should/not' matchers to minitest 'assert/refute'"
34
- expect.text "It's not magic, you still need to hand edit your test files after running this"
35
- expect.text "\nUsage:"
36
- expect.text " ing rspec:convert # which is equivalent to"
37
- expect.text " ing rspec:convert files './{test,spec}/**/*.rb' --convert-dir 'converted'"
38
- expect.text "\nOptions:"
39
- expect.opt :pattern, "Directory glob pattern for test files",
40
- :type => :string, :default => './{test,spec}/**/*.rb'
41
- expect.opt :convert_dir, "Subdirectory to save converted files",
42
- :type => :string, :default => 'converted'
43
- end
44
-
45
- include Ing::Files
46
-
47
- attr_accessor :shell, :options, :destination_root, :source_root
48
-
49
- def destination_root; @destination_root ||= Dir.pwd; end
50
- def source_root; @source_root ||= File.dirname(__FILE__); end
51
-
52
- def input_files
53
- @input_files ||= Dir[ File.expand_path(options[:pattern], source_root) ]
54
- end
55
-
56
- def converted_files
57
- input_files.map {|f|
58
- File.join( File.dirname(f), options[:convert_dir], File.basename(f) )
59
- }
60
- end
61
-
62
- def conversion_map
63
- input_files.zip(converted_files)
64
- end
65
-
66
- def initialize(options)
67
- self.options = options
68
- end
69
-
70
- def call(pattern=nil)
71
- options[:pattern] = pattern || options[:pattern]
72
- shell.say "Processing #{input_files.length} input files: #{options[:pattern]}" if verbose?
73
- conversion_map.each do |input_f, output_f|
74
- new_lines = convert_lines(input_f)
75
- create_file output_f, new_lines.join
76
- end
77
- end
78
- alias :files :call
79
-
80
- private
81
-
82
- def convert_lines(fname)
83
- count = 0; accum = []
84
- File.open(fname) do |f|
85
- f.each_line do |line|
86
- new_line = GSUBS.inject(line) do |str, (rx, replace)|
87
- str = str.gsub(rx, replace)
88
- end
89
- count += 1 if line != new_line
90
- accum << new_line
91
- end
92
- end
93
- shell.say_status(:convert,
94
- "#{relative_to_original_destination_root(fname)}: " +
95
- "#{count} changes",
96
- :green) if verbose?
97
- accum
98
- end
99
-
100
- end
101
-
102
- end
1
+ require_relative 'examples/rspec_convert.rb'
2
+ require_relative 'examples/rake_pipeline.rb'
@@ -9,11 +9,15 @@
9
9
  }
10
10
 
11
11
  def self.specify_options(parser)
12
- parser.banner "List all tasks within specified namespace"
12
+ parser.banner "List all tasks by name or in specified namespace"
13
13
  parser.text "\nUsage:"
14
- parser.text " ing list # list all built-in ing commands"
15
- parser.text " ing list rspec # list all ing commands in rspec namespace, or"
16
- parser.text " ing list --namespace rspec"
14
+ parser.text " ing list # list all built-in ing commands"
15
+ parser.text " ing list -n rspec # list all commands in rspec namespace"
16
+ parser.text " ing list rspec # search for commands that match /.*rspec/ (in any namespace)"
17
+ parser.text " ing list rspec --all # include modules that don't have a description in list (not recommended)"
18
+ parser.text " ing list -n rspec conv # search for commands that match /.*conv/ in rspec namespace"
19
+ parser.text "\nOptions:"
20
+ parser.opt :all, "List all tasks including modules that don't have a description", :default => false
17
21
  end
18
22
 
19
23
  include Ing::CommonOptions
@@ -36,32 +40,57 @@
36
40
  require_ing_file
37
41
  end
38
42
 
39
- def call(ns=nil)
43
+ def call(s=nil)
40
44
  before
41
- mod = _namespace_class(ns)
42
- data = mod.constants.map do |c|
43
- klass = mod.const_get(c)
44
- desc = (Command.new(klass).describe || '')[/.+$/]
45
- [ "ing #{Ing::Util.encode_class(mod)}:#{Ing::Util.encode_class_names([c])}",
46
- (desc || '(no description)').chomp
47
- ]
48
- end.sort
49
- shell.say desc_lines(mod, data).join("\n")
45
+ if s && !options[:namespace_given]
46
+ search_all s
47
+ else
48
+ search s
49
+ end
50
+ end
51
+
52
+ def search(s)
53
+ _do_search(_namespace_class, %r|.*#{s}|, false)
54
+ end
55
+
56
+ def search_all(s)
57
+ _do_search(::Object, %r|.*#{s}|, true)
50
58
  end
51
59
 
52
60
  private
61
+
53
62
  def _namespace_class(ns=options[:namespace])
54
- return ::Ing::Commands unless ns
55
63
  Util.decode_class(ns)
56
64
  end
57
-
58
- def desc_lines(mod, data)
65
+
66
+ def _do_search(mod, expr, recurse)
67
+ data = filtered_commands(mod, recurse, expr).map do |(cmd, klass)|
68
+ desc = (Command.new(klass).describe || '')[/.+$/]
69
+ cmd_and_description(cmd, desc) if options[:all] || desc
70
+ end.compact.sort
71
+ title = "All tasks #{options[:all] ? '' : 'with description'}"
72
+ shell.say desc_lines(mod, data, title).join("\n")
73
+ end
74
+
75
+ def filtered_commands(mod, recurse, expr)
76
+ Util.ing_commands(mod, recurse).select {|(cmd, klass)|
77
+ expr =~ cmd
78
+ }
79
+ end
80
+
81
+ def cmd_and_description(cmd, desc)
82
+ [ "ing #{cmd}",
83
+ (desc || '(no description)').chomp
84
+ ]
85
+ end
86
+
87
+ def desc_lines(mod, data, title="all tasks")
59
88
  colwidths = data.inject([0,0]) {|max, (line, desc)|
60
89
  max[0] = line.length if line.length > max[0]
61
90
  max[1] = desc.length if desc.length > max[1]
62
91
  max
63
92
  }
64
- ["#{mod}: all tasks",
93
+ ["#{mod}: #{title}",
65
94
  "-" * 80
66
95
  ] +
67
96
  data.map {|line, desc|
@@ -13,8 +13,10 @@ module Ing
13
13
 
14
14
  attr_accessor :inherited_options
15
15
 
16
+ # On subclassing, deep copy the merge of current options into inherited
17
+ # options
16
18
  def inherited(subclass)
17
- subclass.inherited_options = self.options.dup
19
+ subclass.inherited_options = Marshal.load(Marshal.dump(self.all_options))
18
20
  end
19
21
 
20
22
  def inherited_option?(name)
@@ -44,6 +46,7 @@ module Ing
44
46
 
45
47
  # Modify the default for option +name+ to +val+.
46
48
  # Option will be created if it doesn't exist.
49
+ #
47
50
  def default(name, val)
48
51
  modify_option name, {:default => val}
49
52
  end
@@ -66,7 +69,8 @@ module Ing
66
69
  alias option opt
67
70
 
68
71
  # Build option parser based on desc, usage, and options (including
69
- # inherited options). This method is called by `Ing::Dispatcher`.
72
+ # inherited options). This method is called by `Ing::Command`.
73
+ # Note that this assumes the syntax of the Trollop parser.
70
74
  #
71
75
  def specify_options(parser)
72
76
  desc_lines.each do |line|
@@ -108,6 +112,12 @@ module Ing
108
112
  @options ||= {}
109
113
  end
110
114
 
115
+ # Options merged into inherited options. This is only used by the
116
+ # +inherited+ hook (on subclassing), and should not be used otherwise.
117
+ def all_options
118
+ (inherited_options || {}).merge(options)
119
+ end
120
+
111
121
  protected
112
122
 
113
123
  def set_options(o) #:nodoc:
@@ -25,6 +25,22 @@
25
25
  list.inject(base) {|m, klass| m.const_get(klass, false)}
26
26
  end
27
27
 
28
+ # search for {modules, callables} under base
29
+ # note this does not pick up aliased constants right now
30
+ def ing_commands(base, recurse=false, init={})
31
+ base.constants(false).each do |c|
32
+ v = base.const_get(c)
33
+ next if init.values.include?(v)
34
+ if v.respond_to?(:constants)
35
+ init[ encode_class(v) ] = v
36
+ ing_commands(v,true,init) if recurse
37
+ elsif v.respond_to?(:call)
38
+ init[ encode_class_names(base.to_s.split('::') + [c]) ] = v
39
+ end
40
+ end
41
+ init
42
+ end
43
+
28
44
  def option?(arg)
29
45
  !!(/^-{1,2}/ =~ arg)
30
46
  end
@@ -1,3 +1,3 @@
1
1
  module Ing
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
@@ -51,4 +51,26 @@ describe Ing::Task do
51
51
 
52
52
  end
53
53
 
54
+ describe "triple inheritance" do
55
+
56
+ subject { ["mega_task"] }
57
+
58
+ it "help should display all the options defined by the task and its superclasses" do
59
+ output = capture_help(subject)
60
+ assert_match(/^\s*--fast/, output)
61
+ assert_match(/^\s*--altitude/, output)
62
+ assert_match(/^\s*--yards/, output)
63
+ assert_match(/^\s*--color/, output)
64
+ assert_match(/^\s*--gallons/, output)
65
+ assert_match(/^\s*--insurance/, output)
66
+ end
67
+
68
+ it "run should reflect modifications to superclass options" do
69
+ output = capture_help(subject)
70
+ assert_match(/^\s*--fast:.+/, output)
71
+ assert_match(/^\s*--color.+\(default: blue\)/, output)
72
+ end
73
+
74
+ end
75
+
54
76
  end
@@ -59,4 +59,15 @@ class BigTask < SimpleTask
59
59
  default :fast, true
60
60
  modify_option :altitude, :short => 'l', :default => 2500
61
61
 
62
+ end
63
+
64
+ class MegaTask < BigTask
65
+
66
+ desc "Monsterous"
67
+ opt :gallons, "Gallons of paint", :type => :integer, :default => 45
68
+ opt :insurance, "Has insurance"
69
+
70
+ default :fast, false
71
+ modify_option :color, :default => "blue"
72
+
62
73
  end
data/todo.yml CHANGED
@@ -1,5 +1,8 @@
1
1
  Ing todo
2
2
  ---
3
+ - add tests for List, Help built-in commands
3
4
  - add Shell::Color
4
5
  - remove global Ing.shell_class, specify via color switch
5
6
  - incorporate gsub_file patch, patches to Shell
7
+ - rewrite README centered on simplest usages and move the rest to MORE pages
8
+ - nicer error handling for bad input
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-20 00:00:00.000000000Z
12
+ date: 2012-09-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
16
- requirement: &7756700 !ruby/object:Gem::Requirement
16
+ requirement: &9181600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *7756700
24
+ version_requirements: *9181600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: fakeweb
27
- requirement: &7756220 !ruby/object:Gem::Requirement
27
+ requirement: &9181100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *7756220
35
+ version_requirements: *9181100
36
36
  description: ! "\nAn alternative to Rake and Thor, Ing has a command-line syntax similar
37
37
  to \nThor's, and it incorporates Thor's (Rails') generator methods and shell \nconventions.
38
38
  But unlike Thor or Rake, it does not define its own DSL. Your tasks\ncorrespond
@@ -52,6 +52,7 @@ files:
52
52
  - README.md
53
53
  - TASKS.md
54
54
  - bin/ing
55
+ - examples/rake_pipeline.rb
55
56
  - examples/rspec_convert.rb
56
57
  - ing.gemspec
57
58
  - ing.rb