cjohansen-juicer 0.2.0 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/History.txt +17 -5
  2. data/Manifest.txt +33 -15
  3. data/Rakefile +22 -1
  4. data/Readme.rdoc +68 -32
  5. data/bin/juicer +1 -0
  6. data/lib/juicer.rb +26 -1
  7. data/lib/juicer/binary.rb +173 -0
  8. data/lib/juicer/cache_buster.rb +45 -0
  9. data/lib/juicer/chainable.rb +1 -0
  10. data/lib/juicer/cli.rb +13 -8
  11. data/lib/juicer/command/install.rb +59 -0
  12. data/lib/juicer/command/list.rb +50 -0
  13. data/lib/juicer/command/merge.rb +130 -31
  14. data/lib/juicer/command/util.rb +32 -0
  15. data/lib/juicer/command/verify.rb +60 -0
  16. data/lib/juicer/core.rb +61 -0
  17. data/lib/juicer/css_cache_buster.rb +106 -0
  18. data/lib/juicer/install/base.rb +186 -0
  19. data/lib/juicer/install/jslint_installer.rb +51 -0
  20. data/lib/juicer/install/rhino_installer.rb +52 -0
  21. data/lib/juicer/install/yui_compressor_installer.rb +66 -0
  22. data/lib/juicer/jslint.rb +90 -0
  23. data/lib/juicer/merger/base.rb +74 -72
  24. data/lib/juicer/merger/dependency_resolver.rb +34 -16
  25. data/lib/juicer/merger/stylesheet_merger.rb +71 -1
  26. data/lib/juicer/minifyer/yui_compressor.rb +20 -43
  27. data/tasks/test/setup.rake +35 -0
  28. data/test/juicer/command/test_install.rb +53 -0
  29. data/test/juicer/command/test_list.rb +69 -0
  30. data/test/juicer/command/test_merge.rb +160 -0
  31. data/test/juicer/command/test_util.rb +54 -0
  32. data/test/juicer/command/test_verify.rb +33 -0
  33. data/test/juicer/install/test_installer_base.rb +195 -0
  34. data/test/juicer/install/test_jslint_installer.rb +54 -0
  35. data/test/juicer/install/test_rhino_installer.rb +57 -0
  36. data/test/juicer/install/test_yui_compressor_installer.rb +56 -0
  37. data/test/juicer/merger/test_base.rb +2 -3
  38. data/test/juicer/merger/test_css_dependency_resolver.rb +8 -4
  39. data/test/juicer/merger/test_javascript_dependency_resolver.rb +6 -7
  40. data/test/juicer/merger/test_javascript_merger.rb +1 -2
  41. data/test/juicer/merger/test_stylesheet_merger.rb +118 -2
  42. data/test/juicer/minifyer/test_yui_compressor.rb +109 -29
  43. data/test/juicer/test_cache_buster.rb +58 -0
  44. data/test/juicer/test_chainable.rb +7 -0
  45. data/test/juicer/test_core.rb +47 -0
  46. data/test/juicer/test_css_cache_buster.rb +91 -0
  47. data/test/juicer/test_jslint.rb +33 -0
  48. data/test/test_helper.rb +65 -196
  49. metadata +77 -26
  50. data/.gitignore +0 -2
  51. data/juicer.gemspec +0 -38
  52. data/lib/juicer/minifyer/compressor.rb +0 -125
  53. data/test/juicer/minifyer/test_compressor.rb +0 -36
data/History.txt CHANGED
@@ -1,9 +1,21 @@
1
- == 0.2.0 / 2009-xx-xx
1
+ == 0.2.4 / 2009-04-29
2
2
 
3
- * Refactored the minifyers execute method from compress to save
4
- * Refactored Juicer::Merger::FileMerger -> Juicer::Merger::Base
5
- * Refactored the mergers and minifyers to be chainable commands.
6
- * Added Chainable module
3
+ * More robust pattern checking for url() references in CSS files
4
+ * Allow skipping verification
5
+ * Bug fix: Skip cache buster if type=none
6
+ * Bug fix: Quote JsLint command parts to allow for spaces in jar file paths
7
+ * Bug fix: cache buster type wasn't carried all the way (ie had no effect)
8
+
9
+ == 0.2.3 / 2009-03-03
10
+
11
+ * Cache busters in CSS files should only be appended once to each URL
12
+ * Output to merge target should accept directories as well as files (in case of
13
+ directories, file name is generated)
14
+ * Tests should not ship with 3rd party libraries
15
+
16
+ == 0.2.0 / 2009-02-25
17
+
18
+ * First usable release; merge, verify, install targets
7
19
 
8
20
  == 0.1.0 / 2008-12-17
9
21
 
data/Manifest.txt CHANGED
@@ -1,40 +1,58 @@
1
- .gitignore
2
1
  History.txt
3
2
  Manifest.txt
4
3
  Rakefile
5
4
  Readme.rdoc
6
5
  bin/juicer
7
- juicer.gemspec
8
6
  lib/juicer.rb
7
+ lib/juicer/binary.rb
8
+ lib/juicer/cache_buster.rb
9
9
  lib/juicer/chainable.rb
10
10
  lib/juicer/cli.rb
11
+ lib/juicer/command/install.rb
12
+ lib/juicer/command/list.rb
11
13
  lib/juicer/command/merge.rb
14
+ lib/juicer/command/util.rb
15
+ lib/juicer/command/verify.rb
16
+ lib/juicer/core.rb
17
+ lib/juicer/css_cache_buster.rb
18
+ lib/juicer/install/base.rb
19
+ lib/juicer/install/jslint_installer.rb
20
+ lib/juicer/install/rhino_installer.rb
21
+ lib/juicer/install/yui_compressor_installer.rb
22
+ lib/juicer/jslint.rb
12
23
  lib/juicer/merger/base.rb
13
24
  lib/juicer/merger/css_dependency_resolver.rb
14
25
  lib/juicer/merger/dependency_resolver.rb
15
26
  lib/juicer/merger/javascript_dependency_resolver.rb
16
27
  lib/juicer/merger/javascript_merger.rb
17
28
  lib/juicer/merger/stylesheet_merger.rb
18
- lib/juicer/minifyer/compressor.rb
19
29
  lib/juicer/minifyer/yui_compressor.rb
20
- test/data/Changelog.txt
21
- test/data/a.css
22
- test/data/a.js
23
- test/data/b.css
24
- test/data/b.js
25
- test/data/mappe/a.css
26
- test/data/mappe/c.css
27
- test/data/mappe/enda_en_mappe/a.css
28
- test/data/version-test.txt
29
- test/data/version.txt
30
- test/data/version2.txt
30
+ tasks/test/setup.rake
31
+ test/bin/jslint.js
32
+ test/bin/rhino1_7R1.zip
33
+ test/bin/rhino1_7R2-RC1.zip
34
+ test/bin/yuicompressor
35
+ test/bin/yuicompressor-2.3.5.zip
36
+ test/bin/yuicompressor-2.4.2.zip
37
+ test/juicer/command/test_install.rb
38
+ test/juicer/command/test_list.rb
39
+ test/juicer/command/test_merge.rb
40
+ test/juicer/command/test_util.rb
41
+ test/juicer/command/test_verify.rb
42
+ test/juicer/install/test_installer_base.rb
43
+ test/juicer/install/test_jslint_installer.rb
44
+ test/juicer/install/test_rhino_installer.rb
45
+ test/juicer/install/test_yui_compressor_installer.rb
31
46
  test/juicer/merger/test_base.rb
32
47
  test/juicer/merger/test_css_dependency_resolver.rb
33
48
  test/juicer/merger/test_javascript_dependency_resolver.rb
34
49
  test/juicer/merger/test_javascript_merger.rb
35
50
  test/juicer/merger/test_stylesheet_merger.rb
36
- test/juicer/minifyer/test_compressor.rb
37
51
  test/juicer/minifyer/test_yui_compressor.rb
52
+ test/juicer/test_cache_buster.rb
38
53
  test/juicer/test_chainable.rb
54
+ test/juicer/test_core.rb
55
+ test/juicer/test_css_cache_buster.rb
56
+ test/juicer/test_jslint.rb
39
57
  test/test_helper.rb
40
58
  test/test_juicer.rb
data/Rakefile CHANGED
@@ -6,11 +6,16 @@ begin
6
6
  require 'bones'
7
7
  Bones.setup
8
8
  rescue LoadError
9
- load 'tasks/setup.rb'
9
+ begin
10
+ load 'tasks/setup.rb'
11
+ rescue LoadError
12
+ raise RuntimeError, '### please install the "bones" gem ###'
13
+ end
10
14
  end
11
15
 
12
16
  ensure_in_path 'lib'
13
17
  require 'juicer'
18
+ load 'tasks/test/setup.rake'
14
19
 
15
20
  task :default => 'test:run'
16
21
 
@@ -21,7 +26,23 @@ PROJ.url = 'http://www.cjohansen.no/en/projects/juicer'
21
26
  PROJ.version = Juicer::VERSION
22
27
  PROJ.rubyforge.name = 'juicer'
23
28
  PROJ.readme_file = 'Readme.rdoc'
29
+ PROJ.exclude = %w(tmp$ bak$ ~$ CVS \.svn ^pkg ^doc \.git ^rcov ^test\/data gemspec ^test\/bin)
30
+ PROJ.rdoc.remote_dir = 'juicer'
24
31
 
25
32
  PROJ.spec.opts << '--color'
26
33
 
34
+ PROJ.gem.extras[:post_install_message] = <<-MSG
35
+ Juicer does not ship with third party libraries. You probably want to install
36
+ Yui Compressor and JsLint now:
37
+
38
+ juicer install yui_compressor
39
+ juicer install jslint
40
+
41
+ Happy juicing!
42
+ MSG
43
+
44
+ CLOBBER.include "test/data"
45
+
27
46
  depend_on 'cmdparse'
47
+ depend_on 'hpricot'
48
+ depend_on 'rubyzip'
data/Readme.rdoc CHANGED
@@ -1,20 +1,32 @@
1
1
  = Juicer
2
+ Official URL: http://github.com/cjohansen/juicer/tree/master
2
3
  Christian Johansen (http://www.cjohansen.no)
3
4
 
4
5
  == DESCRIPTION:
5
6
 
6
- Juicer is a command line tool aimed at easing JavaScript and CSS development.
7
- Currently it only provides a wrapper to YUI Compressor along with a module that
8
- can dynamically link together files, but there are plans for more functionality.
7
+ Juicer is a command line tool that helps you ship frontend code for production.
8
+
9
+ High level overview; Juicer can
10
+
11
+ * figure out which files depend on each other and merge them together, reducing
12
+ the number of http requests per page view, thus improving performance
13
+ * use YUI Compressor to compress code, thus improving performance
14
+ * verify that your JavaScript is safe to minify/compress by running JsLint on it
15
+ * cycle asset hosts in CSS files
16
+ * add "cache busters" to URLs in CSS files
17
+ * recalculate relative URLs in CSS files, as well as convert them to absolute
18
+ (or convert absolute URLs to relative URLs)
9
19
 
10
20
  == FEATURES:
11
21
 
22
+ === Merging and minifying
23
+
12
24
  Juicer can read @import statements in CSS files and use them to combine all your
13
25
  stylesheets into a single file. This file may be minified using the YUI
14
26
  Compressor. Eventually it will support other minifying tools too.
15
27
 
16
28
  Juicer can treat your JavaScript files much the same way too, parsing a comment
17
- switch @depends, as this example shows:
29
+ switch @depend, as this example shows:
18
30
 
19
31
  /**
20
32
  * My script file
@@ -29,28 +41,51 @@ Running <tt>juicer merge</tt> on this file will result in a minified file
29
41
  <tt>filename.min.js</tt> containing the file jquery-1.2.0.js (located in the
30
42
  same directory) and the code above.
31
43
 
32
- == 0.1.0 STATUS:
44
+ You can use @import (CSS files) and @depend (JavaScript) recursively, effectively
45
+ creating a dependency chain for Juicer to climb and merge.
46
+
47
+ === Paths
48
+
49
+ When merging CSS files, you may want to merge CSS files in different directories.
50
+ You may also want the resulting CSS file to end up in another directory as well.
51
+ Juicer automatically recalculates referenced URLs to reflect this change.
52
+
53
+ Absolute URLs are not changed by default, but if you provide juicer merge with
54
+ --document-root [DIR] and --relative-urls then absolute URLs are converted to
55
+ URLs relative to output directory. You can also use --absolute-urls to convert
56
+ all URLs to absolute ones.
57
+
58
+ === Cache busters
33
59
 
34
- Juicer is currently in a very early stage, please expect it to be unstable,
35
- poorly documented and otherwise unfinished. Some of this code is a bit old, and
36
- a brush up is planned that will likely result in several API changes.
60
+ Juicer supports so-called cache busters. A cache buster is a pattern in a path
61
+ whose only purpose is to "trick" browsers to redownload a file when it has
62
+ changed in cases where a far future expires header is used.
63
+
64
+ There are two types of cache busters; soft ones add a parameter to the URL, like
65
+ so: http://assets/images/1.png?cb1234567890, ie the letters "cb" (as in cache
66
+ buster) and then the timestamp of the files mtime.
67
+
68
+ Unfortunately, the popular web proxy Squid shipped for some time with a default
69
+ configuration which would not treat a URL as a "new" URL if the only thing changed
70
+ was the GET parameters. For this reason Juicer provides hard cache busters.
71
+
72
+ Hard cache busters result in URLs such as http://assets/images/1-cb1234567890.png,
73
+ ie URLs that require either renaming of files, or (more conveniently) a web
74
+ server configuration that will forward URLs to the right files anyway.
37
75
 
38
76
  == PLANNED FEATURES:
39
77
 
40
- There are several things on the pipeline:
78
+ Juicer 0.2.0 is the first usable release. Work will continue from here. Improving
79
+ documentation and APIs is one concern, but there are also new features planned:
41
80
 
42
81
  * Support more minifiers, JsMin (Ruby port), Packer and possibly others
43
- * Wrap code quality assurance tools, such as JsLint and CSS Tidy
44
- juicer check design/*
45
- * A tool to build a whole proect based on a configuration file or something
46
- like that
47
-
48
- As you see, Juicer will mostly rely heavily on other peoples great work. Juicers
49
- strength will be that it provides a single simple to use interface to run these
50
- tools on your project, as well as sewing it all together.
82
+ * Add support for CssTidy to compress CSS files
83
+ * juicer build, a command that can build several files in one swoop using a
84
+ configuration file
85
+ * juicer doc, a command that produces documentation using YUI Doc or JsDoc
51
86
 
52
87
  If you have any ideas, feature requests, want to contribute or whatever, fork
53
- the proect on github, or get in touch through christian (at) cjohansen.no.
88
+ the project on github, or get in touch through christian (at) cjohansen.no.
54
89
 
55
90
  == SYNOPSIS:
56
91
 
@@ -60,33 +95,34 @@ the proect on github, or get in touch through christian (at) cjohansen.no.
60
95
  juicer merge myfile.js
61
96
  -> Produces myfile.min.js, minified and combined
62
97
 
98
+ juicer help
99
+
63
100
  == REQUIREMENTS:
64
101
 
65
- In order to use YUI Compressor you need Java installed and the java executable
66
- available on your path.
102
+ In order to use YUI Compressor and JsMin (requires Rhino) you need Java
103
+ installed and the java executable available on your path.
67
104
 
68
105
  == INSTALL:
69
106
 
70
- $ wget http://www.cjohansen.no/juicer-0.1.0.gem
71
- $ gem install juicer-0.1.0.gem
107
+ $ gem install juicer
108
+ $ juicer install yui_compressor
109
+ $ juicer install jslint
110
+
111
+ You need Java installed and available on your PATH. During gem installation,
112
+ Juicer will download and install YUI Compressor, JsLint and Rhino for you.
72
113
 
73
- You need Java installed, and you need the YUI Compressor jar file. Get it from
74
- http://developer.yahoo.com/yui/compressor/
114
+ == For developers
75
115
 
76
- Download the YUI Compressor package and unzip on your file system. Either create
77
- an environment variable <tt>$YUIC_HOME</tt> that points to where the file is
78
- found, or provide the path like so:
79
- juicer merge --path ~/sources/yuicompressor/build [...]
116
+ Before running tests you should run
117
+ rake test:setup
80
118
 
81
- Alternatively you can keep a copy of the jar file in the same directory that you
82
- run the <tt>juicer</tt> command from. I imagine that would only make sense in a
83
- testing scenario.
119
+ which brings in third party libraries (ie, requires a working network connection)
84
120
 
85
121
  == LICENSE:
86
122
 
87
123
  (The MIT License)
88
124
 
89
- Copyright (c) 2008 Christian Johansen
125
+ Copyright (c) 2008-2009 Christian Johansen
90
126
 
91
127
  Permission is hereby granted, free of charge, to any person obtaining
92
128
  a copy of this software and associated documentation files (the
data/bin/juicer CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ require "rubygems"
2
3
  dir = File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__)
3
4
  base = File.expand_path(File.join(dir, %w[.. lib juicer]))
4
5
  require base
data/lib/juicer.rb CHANGED
@@ -1,9 +1,13 @@
1
+ require "logger"
2
+
1
3
  module Juicer
2
4
 
3
5
  # :stopdoc:
4
- VERSION = '0.2.0'
6
+ VERSION = '0.2.4'
5
7
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
8
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
9
+ LOGGER = Logger.new(STDOUT)
10
+ @@home = nil
7
11
  # :startdoc:
8
12
 
9
13
  # Returns the version string for the library.
@@ -12,6 +16,24 @@ module Juicer
12
16
  VERSION
13
17
  end
14
18
 
19
+ # Returns the installation directory for Juicer
20
+ #
21
+ def self.home
22
+ return @@home if @@home
23
+ return ENV['JUICER_HOME'] if ENV['JUICER_HOME']
24
+ return File.join(ENV['HOME'], ".juicer") if ENV['HOME']
25
+ return File.join(ENV['APPDATA'], "juicer") if ENV['APPDATA']
26
+ return File.join(ENV['HOMEDRIVE'], ENV['HOMEPATH'], "juicer") if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
27
+ return File.join(ENV['USERPROFILE'], "juicer") if ENV['USERPROFILE']
28
+ return File.join(ENV['Personal'], "juicer") if ENV['Personal']
29
+ end
30
+
31
+ # Set home directory
32
+ #
33
+ def self.home=(home)
34
+ @@home = home
35
+ end
36
+
15
37
  # Returns the library path for the module. If any arguments are given,
16
38
  # they will be joined to the end of the libray path using
17
39
  # <tt>File.join</tt>.
@@ -43,3 +65,6 @@ module Juicer
43
65
  end
44
66
 
45
67
  Juicer.require_all_libs_relative_to(__FILE__)
68
+
69
+ class FileNotFoundError < Exception
70
+ end
@@ -0,0 +1,173 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "chainable"))
2
+
3
+ module Juicer
4
+
5
+ # Defines an abstract implementation of a binary that needs to be "shelled
6
+ # out" to be run. Provides a starting point when wrapping and API around a
7
+ # shell binary.
8
+ #
9
+ # The module requires the including class to define the default_options
10
+ # method. It should return a hash of options where options are keys and
11
+ # default values are the values. Only options defined in this hash will be
12
+ # allowed to set on the binary.
13
+ #
14
+ module Binary
15
+
16
+ # Initialize binary with options
17
+ # options = Hash of options, optional
18
+ #
19
+ def initialize(binary, options = {})
20
+ @options = self.respond_to?(:defualt_options) ? default_options.merge(options) : options
21
+ @opt_set = false
22
+ @command = nil
23
+ @binary = binary
24
+ @path = []
25
+ end
26
+
27
+ def path
28
+ @path
29
+ end
30
+
31
+ # Run command
32
+ #
33
+ def execute(params = nil)
34
+ #puts "#{self.command} #{params}"
35
+ cmd = IO.popen("#{self.command} #{params}", "r")
36
+ results = cmd.gets(nil)
37
+ cmd.close
38
+ results
39
+ end
40
+
41
+ # Return the value of a given option
42
+ # opt = The option to return value for
43
+ #
44
+ def get_opt(opt)
45
+ @options[opt] || nil
46
+ end
47
+
48
+ # Return options as a cli arguments string. Optionally accepts a list of
49
+ # options to exclude from the generated string
50
+ #
51
+ def options(*excludes)
52
+ excludes = excludes.flatten.collect { |exc| exc.to_sym }
53
+ @options.inject("") do |str, opt|
54
+ if opt[1].nil? || excludes.include?(opt[0].to_sym)
55
+ str
56
+ else
57
+ val = opt[1] == true ? '' : opt[1]
58
+ option = opt[0].to_s
59
+ option = (option.length == 1 ? "-" : "--") + option.gsub('_', '-')
60
+ "#{str} #{option} #{val}".strip
61
+ end
62
+ end
63
+ end
64
+
65
+ # Set an option. Important: you can only set options that are predefined by the
66
+ # implementing class
67
+ # opt = The option to set
68
+ # value = The value of the option
69
+ #
70
+ def set_opt(opt, value)
71
+ opt = opt.to_sym
72
+ if @options.key?(opt)
73
+ @options[opt] = value
74
+ @opt_set = true
75
+ else
76
+ msg = "Illegal option '#{opt}', specify one of: #{@options.keys.join(', ')}"
77
+ raise ArgumentError.new(msg)
78
+ end
79
+ end
80
+
81
+ # Performs simple parsing of a string of parameters. All recognized
82
+ # parameters are set, non-existent arguments raise an ArgumentError
83
+ #
84
+ def set_opts(options)
85
+ options = options.split " "
86
+ option = nil
87
+ regex = /^--?([^=]*)(=(.*))?/
88
+
89
+ while word = options.shift
90
+ if word =~ regex
91
+ if option
92
+ set_opt option, true
93
+ end
94
+
95
+ if $3
96
+ set_opt $1, $3
97
+ else
98
+ option = $1
99
+ end
100
+ else
101
+ set_opt option, word
102
+ option = nil
103
+ end
104
+ end
105
+ end
106
+
107
+ # Constructs the command to use
108
+ #
109
+ def command
110
+ return @command if !@opt_set && @command
111
+ @opt_set = false
112
+ @command = "#{@binary} #{options}"
113
+ end
114
+
115
+ # Locate the binary to execute. The binary is searched for in the
116
+ # following places:
117
+ #
118
+ # 1) The paths specified through my_binary.path << "/usr/bin"
119
+ # 2) The path specified by the given environment variable
120
+ # 3) Current working directory
121
+ #
122
+ # The name of the binary may be a glob pattern, resulting in +locate+
123
+ # returning an array of matches. This is useful in cases where the path
124
+ # is expected to store several versions oof a binary in the same directory,
125
+ # like /usr/bin/ruby /usr/bin/ruby1.8 /usr/bin/ruby1.9
126
+ #
127
+ # +locate+ always returns an array, or nil if no binaries where found.
128
+ # The result is always all files matching the given pattern in *one* of
129
+ # the specified paths - ie the first path where the pattern matches
130
+ # something.
131
+ #
132
+ def locate(bin_glob, env = nil)
133
+ path << ENV[env] if env && ENV.key?(env) && File.exist?(ENV[env])
134
+
135
+ (path << Dir.pwd).each do |path|
136
+ files = Dir.glob(File.expand_path(File.join(path, bin_glob)))
137
+ return files unless files.empty?
138
+ end
139
+
140
+ nil
141
+ end
142
+
143
+ # Allows for options to be set and read directly on the object as though they were
144
+ # standard attributes. compressor.verbose translates to
145
+ # compressor.get_opt('verbose') and compressor.verbose = true to
146
+ # compressor.set_opt('verbose', true)
147
+ def method_missing(m, *args)
148
+ if @options.key?(m)
149
+ # Only hit method_missing once per option
150
+ self.class.send(:define_method, m) do # def verbose
151
+ get_opt(m) # get_opt(:verbose)
152
+ end # end
153
+
154
+ return get_opt(m)
155
+ end
156
+
157
+ return super unless m.to_s =~ /=$/
158
+
159
+ opt = m.to_s.sub(/=$/, "").to_sym
160
+
161
+ if @options.key?(opt)
162
+ # Only hit method_missing once per option
163
+ self.class.send(:define_method, m) do # def verbose=(val)
164
+ set_opt(opt, args[0]) # set_opt(:verbose, val)
165
+ end # end
166
+
167
+ return set_opt(opt, args[0])
168
+ end
169
+
170
+ super
171
+ end
172
+ end
173
+ end