csd 0.1.9 → 0.1.10

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 (48) hide show
  1. data/.gitignore +5 -1
  2. data/Rakefile +7 -7
  3. data/VERSION +1 -1
  4. data/bin/ai +1 -1
  5. data/csd.gemspec +21 -9
  6. data/lib/csd.rb +15 -8
  7. data/lib/csd/application/decklink.rb +27 -0
  8. data/lib/csd/application/decklink/about.yml +7 -0
  9. data/lib/csd/application/decklink/base.rb +62 -0
  10. data/lib/csd/application/default.rb +5 -1
  11. data/lib/csd/application/default/base.rb +10 -0
  12. data/lib/csd/application/minisip.rb +8 -5
  13. data/lib/csd/application/minisip/about.yml +1 -1
  14. data/lib/csd/application/minisip/base.rb +29 -90
  15. data/lib/csd/application/minisip/component.rb +8 -0
  16. data/lib/csd/application/minisip/component/core.rb +288 -0
  17. data/lib/csd/application/minisip/component/ffmpeg.rb +78 -0
  18. data/lib/csd/application/minisip/component/gnome.rb +48 -0
  19. data/lib/csd/application/minisip/component/hdviper.rb +49 -0
  20. data/lib/csd/application/minisip/component/plugins.rb +53 -0
  21. data/lib/csd/application/minisip/component/x264.rb +42 -0
  22. data/lib/csd/application/minisip/error.rb +11 -5
  23. data/lib/csd/application/minisip/options/common.rb +4 -4
  24. data/lib/csd/application/minisip/options/compile.rb +10 -16
  25. data/lib/csd/application/minisip/unix.rb +19 -159
  26. data/lib/csd/application/minisip/unix/darwin.rb +1 -11
  27. data/lib/csd/application/minisip/unix/linux.rb +1 -1
  28. data/lib/csd/application/minisip/unix/linux/debian.rb +6 -14
  29. data/lib/csd/application/minisip/unix/linux/debian/ubuntu10.rb +6 -4
  30. data/lib/csd/applications.rb +16 -21
  31. data/lib/csd/commands.rb +34 -7
  32. data/lib/csd/error.rb +27 -11
  33. data/lib/csd/extensions/core/kernel.rb +9 -19
  34. data/lib/csd/extensions/core/object.rb +1 -0
  35. data/lib/csd/extensions/core/string.rb +1 -1
  36. data/lib/csd/extensions/gem/platform.rb +9 -3
  37. data/lib/csd/options_parser.rb +3 -3
  38. data/lib/csd/user_interface/base.rb +8 -5
  39. data/lib/csd/user_interface/cli.rb +9 -1
  40. data/lib/csd/user_interface/silent.rb +7 -4
  41. data/lib/csd/vendor/zentest/zentest_assertions.rb +39 -35
  42. data/test/application/test_minisip.rb +65 -26
  43. data/test/functional/test_applications.rb +4 -4
  44. data/test/functional/test_commands.rb +26 -2
  45. data/test/helper.rb +9 -5
  46. data/test/unit/test_pathname.rb +1 -1
  47. data/test/unit/test_platform.rb +30 -0
  48. metadata +18 -6
@@ -6,14 +6,14 @@ module CSD
6
6
  module Minisip
7
7
  class Ubuntu10 < Debian
8
8
 
9
- def after_aptitude_dependencies
9
+ def after_aptitude
10
10
  fix_ubuntu_10_04
11
- exit if Options.only_fix_giomm
12
11
  super
13
12
  end
14
13
 
15
14
  def fix_ubuntu_10_04
16
- if Path.giomm_header_backup.file?
15
+ UI.info "Fixing broken Debian libraries (Ubuntu 10.04 only)".green.bold
16
+ if Path.giomm_header_backup.file? and !Options.reveal
17
17
  UI.warn "giomm-2.4 seems to be fixed already, I won't touch it now. Delete #{Path.giomm_header_backup.enquote} to enforce it."
18
18
  else
19
19
  Path.new_giomm_header = File.join(Dir.mktmpdir, 'giomm.h')
@@ -22,11 +22,13 @@ module CSD
22
22
  r.replace '#include <giomm/socket.h>', "/* ----- AI COMMENTING OUT START ----- \n#include <giomm/socket.h>"
23
23
  r.replace '#include <giomm/tcpconnection.h>', "#include <giomm/tcpconnection.h>\n ----- AI COMMENTING OUT END ----- */"
24
24
  end
25
+ # We cannot use Cmd.copy here, because Cmd.copy has no superuser privileges.
26
+ # And since we are for sure on Ubuntu, these commands will work.
25
27
  Cmd.run("sudo cp #{Path.giomm_header} #{Path.giomm_header_backup}")
26
28
  Cmd.run("sudo cp #{Path.new_giomm_header} #{Path.giomm_header}")
27
29
  end
28
30
  end
29
-
31
+
30
32
  end
31
33
  end
32
34
  end
@@ -7,54 +7,49 @@ module CSD
7
7
  # A convenience wrapper to get information about the available applications
8
8
  #
9
9
  class Applications
10
-
10
+
11
11
  # Returns the application module instance of +app_name+. Returns +nil+ if the application could not be found or loaded.
12
12
  #
13
13
  def self.find(app_name)
14
14
  return nil if app_name.to_s.empty?
15
15
  begin
16
- UI.debug "Applications.find: Attempting to require `#{File.join(Path.applications, app_name.to_s)}´."
16
+ UI.debug "#{self}.find got a request to see whether `#{app_name}´ is a valid application or not"
17
17
  require File.join(Path.applications, app_name.to_s)
18
- UI.debug "Applications.find: Attempting to load `#{app_name}´."
18
+ UI.debug "#{self}.find tries to initialize the loaded application `#{app_name}´ now"
19
19
  "CSD::Application::#{app_name.to_s.camelize}".constantize
20
20
  rescue LoadError => e
21
- UI.debug "Applications.find: The Application `#{app_name}´ could not be loaded properly."
22
- UI.debug " Reason: #{e}"
21
+ UI.debug "#{self}.find could not load `#{app_name}´ in #{e.to_s.gsub('no such file to load -- ', '').enquote}"
23
22
  nil
24
23
  end
25
24
  end
26
-
25
+
26
+ # This method returns instantiated modules of all valid applications in an +Array+ or in a block.
27
+ #
27
28
  def self.all(&block)
28
29
  result = []
29
30
  Dir.directories(Path.applications) do |dir|
30
31
  next if dir == 'default'
31
- UI.debug "Applications.all: Identified application directory `#{dir}´."
32
32
  if app = find(dir)
33
- UI.debug "Applications.all: The application `#{dir}´ is valid."
34
33
  block_given? ? yield(app) : result << app
35
34
  end
36
35
  end
37
36
  result
38
37
  end
39
38
 
40
- def self.valid?(name)
41
- list.include?(name)
42
- end
43
-
44
- # This method identifies the desired application and initializes it in to +@@current+.
45
- # It is meant to be very robust, we expect the application to be any one of the first three arguments.
39
+ # This method holds the desired application and initializes its module into +@@current+.
46
40
  #
47
41
  def self.current
48
- @@current ||= begin
49
- Applications.find(ARGV.first) || Applications.find(ARGV.second) || Applications.find(ARGV.third)
50
- end
42
+ # In testmode we don't want to perform caching
43
+ return choose_current if Options.testmode
44
+ # Otherwise we choose and cache the current application module here
45
+ @@current ||= choose_current
51
46
  end
52
47
 
53
- # Forces a reload of the current application. This method is useful for functional tests.
48
+ # This method identifies the desired application. No caching takes place here.
49
+ # It is meant to be very robust, we expect the application to be any one of the first three arguments.
54
50
  #
55
- def self.current!
56
- @@current = false
57
- current
51
+ def self.choose_current
52
+ Applications.find(ARGV.first) || Applications.find(ARGV.second) || Applications.find(ARGV.third)
58
53
  end
59
54
 
60
55
  end
@@ -87,6 +87,31 @@ module CSD
87
87
  result
88
88
  end
89
89
 
90
+ # Creates a new file and writes content to it. Truncates the file if it already had content.
91
+ #
92
+ def touch_and_replace_content(target, content='', params={})
93
+ default_params = { :die_on_failure => true, :internal => false }
94
+ params = default_params.merge(params)
95
+ target = target.pathnamify
96
+ result = CommandResult.new
97
+ unless params[:internal]
98
+ UI.info "Writing content into file #{target} as follows:".cyan
99
+ UI.info "#{content}"
100
+ end
101
+ if Options.reveal
102
+ result.success = true
103
+ else
104
+ begin
105
+ File.open(target, 'w') { |f| f << content }
106
+ result.success = target.file? # TODO: Maybe check for the actual content of the created file here
107
+ rescue Exception => e
108
+ result.reason = "Cannot write to file `#{target}´. Reason: #{e.message}"
109
+ params[:die_on_failure] ? raise(CSD::Error::Command::TouchAndReplaceContentFailed, result.reason) : UI.error(result.reason)
110
+ end
111
+ end
112
+ result
113
+ end
114
+
90
115
  # Copies one or several files to the destination
91
116
  #
92
117
  def copy(src, dest, params={})
@@ -151,9 +176,9 @@ module CSD
151
176
  default_params = { :die_on_failure => true }
152
177
  params = default_params.merge(params)
153
178
  begin
154
- UI.info " Modifying".yellow
179
+ UI.info " Replacing".yellow
155
180
  UI.info " `#{pattern}´".blue
156
- UI.info " to".yellow
181
+ UI.info " with".yellow
157
182
  UI.info " `#{substitution.to_s.gsub("\n", "\n ")}´".white
158
183
  new_file_content = File.read(self.filepath).gsub(pattern.to_s, substitution.to_s)
159
184
  File.open(self.filepath, 'w+') { |file| file << new_file_content } unless Options.reveal
@@ -177,26 +202,28 @@ module CSD
177
202
  #
178
203
  # The following options can be passed as a hash.
179
204
  #
180
- # [+:die_on_failure+] If the exit code of the command was not 0, exit the CSD application (default: +true+).
205
+ # [+:die_on_failure+] If the status code of the command was not 0, raise an Command::RunFailed exception (default: +true+).
181
206
  # [+:announce_pwd+] Before running the command, announce in which path the command will be executed (default: +true+).
182
207
  # [+:verbose+] Instead of printing just one `.´ per command output line, print the full command output lines (default: +false+).
183
208
  # [+:internal+] If this parameter is +true+, there will be no output what-so-ever for running this command. (default: +false+).
209
+ # [+:force_in_reveal+] If this parameter is +true+, the command will be executed, even in <tt>--reveal</tt> mode (default: +false+).
184
210
  #
185
211
  # ==== Returns
186
212
  #
187
213
  # This method returns a CommandResult object with the following values:
188
214
  #
189
- # [+success?+] +true+ if the command was successful, +nil+ if not.
190
- # [+output?+] The command's output as a +String+ (with newline delimiters). Note that the exit code can be accessed via the global variable <tt>$?</tt>
215
+ # [+output?+] The command's output as a +String+ (with newline delimiters). Note that the status code can be accessed via the global variable <tt>$?</tt>.
216
+ # [+status?+] Contains <tt>$?</tt> and all the methods Ruby provides for it.
217
+ # [+success?+] +true+ if the command was successful, +nil+ if not (internally <tt>$?.success?</tt> is called).
191
218
  #
192
219
  def run(cmd, params={})
193
- default_params = { :die_on_failure => true, :announce_pwd => true, :verbose => Options.verbose, :internal => false }
220
+ default_params = { :die_on_failure => true, :announce_pwd => true, :verbose => Options.verbose, :internal => false, :force_in_reveal => false }
194
221
  params = default_params.merge(params)
195
222
  result = CommandResult.new
196
223
  cmd = cmd.to_s
197
224
  UI.info "Running command in #{pwd}".yellow if params[:announce_pwd] and !params[:internal]
198
225
  UI.info cmd.cyan unless params[:internal]
199
- if Options.reveal
226
+ if Options.reveal and !params[:force_in_reveal]
200
227
  result.success = true
201
228
  return result
202
229
  end
@@ -1,11 +1,15 @@
1
1
  # -*- encoding: UTF-8 -*-
2
2
 
3
3
  module CSD
4
- # In this module we will keep all types of errors in a readable hierarchy
4
+ # In this module we will keep all types of errors in a readable hierarchy.
5
+ # The application modules are assigned the following individual error ranges:
6
+ #
7
+ # * +minisip+ has been assigned error status codes 200-280
8
+ # * +decklink+ has been assigned error status codes 280-299
5
9
  #
6
10
  module Error
7
11
 
8
- # All Exceptions raised by CSD must be children of this class.
12
+ # All Exceptions raised by CSD must be children of this class.
9
13
  #
10
14
  class CSDError < StandardError
11
15
  def self.status_code(code = nil)
@@ -18,29 +22,41 @@ module CSD
18
22
  end
19
23
  end
20
24
 
25
+ # Errors in this module are caused by internal AI failures.
26
+ #
27
+ module Internal
28
+ # Somebody tried to run the CSD::Extensions::Core::Pathname.pathnamify method on +nil+. This probably happened in the test-suite when a +Path+ is not set.
29
+ class PathnamifyingNil < CSDError; status_code(1000); end
30
+ end
31
+
21
32
  # Errors in this module are related to command-line options
22
33
  #
23
34
  module Argument
24
- class NoApplication < CSDError; status_code(11); end
25
- class NoAction < CSDError; status_code(12); end
26
- class InvalidOption < CSDError; status_code(50); end
35
+ # The <tt>--help</tt> parameter was given, thus the AI quitted after showing the help.
36
+ class HelpWasRequested < CSDError; status_code(2); end
37
+ # The <tt>--version</tt> parameter was given, thus the AI quitted after showing the AI version number.
38
+ class VersionWasRequested < CSDError; status_code(3); end
39
+ class NoApplication < CSDError; status_code(11); end
40
+ class NoAction < CSDError; status_code(12); end
41
+ class InvalidOption < CSDError; status_code(50); end
27
42
  end
28
43
 
29
44
  # Errors in this module are raised by the Command module
30
45
  #
31
46
  module Command
32
- class RunFailed < CSDError; status_code(60); end
33
- class CdFailed < CSDError; status_code(61); end
34
- class CopyFailed < CSDError; status_code(62); end
35
- class MoveFailed < CSDError; status_code(63); end
47
+ class RunFailed < CSDError; status_code(60); end
48
+ class CdFailed < CSDError; status_code(61); end
49
+ class CopyFailed < CSDError; status_code(62); end
50
+ class MoveFailed < CSDError; status_code(63); end
36
51
  class ReplaceFailed < CSDError; status_code(64); end
37
- class MkdirFailed < CSDError; status_code(65); end
52
+ class MkdirFailed < CSDError; status_code(65); end
53
+ class TouchAndReplaceContentFailed < CSDError; status_code(66); end
38
54
  end
39
55
 
40
56
  # Errors in this module are related to the Application Module Framework
41
57
  #
42
58
  module Application
43
- class OptionsSyntax < CSDError; status_code(100); end
59
+ class OptionsSyntax < CSDError; status_code(100); end
44
60
  class NoInstanceMethod < CSDError; status_code(101); end
45
61
  end
46
62
 
@@ -1,23 +1,13 @@
1
1
  # -*- encoding: UTF-8 -*-
2
2
 
3
- module CSD
4
- module Extensions
5
- module Core
6
- # This module comprises extensions to the Kernel module
7
- #
8
- module Kernel
9
-
10
- # Checks whether the AI was executed with superuser rights (a.k.a. +sudo+). Returns +true+ or +false+.
11
- #
12
- def superuser?
13
- Process.uid == 0
14
- end
15
-
16
- end
17
- end
18
- end
19
- end
20
-
3
+ # This module extends the original Kernel module. Note that methods cannot be added via the +include+ method in this case.
4
+ #
21
5
  module Kernel #:nodoc:
22
- include CSD::Extensions::Core::Kernel
6
+
7
+ # Checks whether the AI was executed with superuser rights (a.k.a. +sudo+). Returns +true+ or +false+.
8
+ #
9
+ def superuser?
10
+ Process.uid == 0
11
+ end
12
+
23
13
  end
@@ -18,6 +18,7 @@ module CSD
18
18
  def pathnamify
19
19
  case self
20
20
  when ::Pathname then self
21
+ when NilClass then raise ::CSD::Error::Internal::PathnamifyingNil
21
22
  else ::Pathname.new(self)
22
23
  end
23
24
  end
@@ -13,7 +13,7 @@ module CSD
13
13
  #
14
14
  # ==== Example
15
15
  #
16
- # 'Hello World'.enquote # => '"Hello World"'
16
+ # 'Hello World'.enquote # => '`Hello World´'
17
17
  #
18
18
  def enquote
19
19
  %Q{"#{self}"}
@@ -16,16 +16,22 @@ module CSD
16
16
  "#{os} (#{cpu}#{version_string})"
17
17
  end
18
18
 
19
+ # Determines whether the OS is Debian or Ubuntu. Returns +true+ or +false+.
20
+ #
21
+ def debian?
22
+ kernel_version and kernel_version =~ /Debian|Ubuntu/
23
+ end
24
+
19
25
  # On linux systems, this method returns the current kernel version.
20
26
  #
21
27
  def kernel_version
22
- Cmd.run('uname --kernel-version', :internal => true).output.to_s.chop if os == 'linux'
28
+ Cmd.run('uname --kernel-version', :internal => true, :force_in_reveal => true).output.to_s.chop if os == 'linux'
23
29
  end
24
30
 
25
31
  # On linux systems, this method returns the current kernel release.
26
32
  #
27
33
  def kernel_release
28
- Cmd.run('uname --kernel-release', :internal => true).output.to_s.chop if os == 'linux'
34
+ Cmd.run('uname --kernel-release', :internal => true, :force_in_reveal => true).output.to_s.chop if os == 'linux'
29
35
  end
30
36
 
31
37
  end
@@ -33,7 +39,7 @@ module CSD
33
39
  end
34
40
  end
35
41
 
36
- module Gem
42
+ module Gem #:nodoc:
37
43
  class Platform #:nodoc:
38
44
  include CSD::Extensions::Gem::Platform
39
45
  end
@@ -26,10 +26,10 @@ module CSD
26
26
  def define_actions_and_scopes
27
27
  if Applications.current
28
28
  # Here we overwrite the default supported actions and scopes with the application specific ones
29
- UI.debug "Loading actions of #{Applications.current}."
29
+ UI.debug "#{self.class} loads the actions of #{Applications.current} now"
30
30
  self.actions = Applications.current.actions
31
31
  # At this point we know that the first argument is no option, but *some* action (may it be valid or not)
32
- UI.debug "Loading scopes of #{Applications.current}."
32
+ UI.debug "#{self.class} loads the scopes of #{Applications.current} now"
33
33
  self.scopes = Applications.current.scopes(self.action)
34
34
  end
35
35
  end
@@ -130,7 +130,7 @@ module CSD
130
130
  end
131
131
  opts.on_tail("-v", "--version", "Show the version of this AI") do
132
132
  puts "CSD Gem Version: #{CSD::Version}".blue
133
- exit
133
+ raise Error::Argument::VersionWasRequested
134
134
  end
135
135
  self.helptext = opts.help
136
136
  end.parse!
@@ -13,19 +13,22 @@ module CSD
13
13
 
14
14
  def indicate_activity
15
15
  end
16
-
16
+
17
+ def ask_yes_no(question, default=nil)
18
+ end
19
+
17
20
  def debug(message)
18
21
  end
19
-
22
+
20
23
  def info(message)
21
24
  end
22
-
25
+
23
26
  def warn(message)
24
27
  end
25
-
28
+
26
29
  def error(message)
27
30
  end
28
-
31
+
29
32
  end
30
33
  end
31
34
  end
@@ -4,7 +4,7 @@ require 'csd/user_interface/base'
4
4
  module CSD
5
5
  module UserInterface
6
6
  class CLI < Base
7
-
7
+
8
8
  include Gem::UserInteraction
9
9
 
10
10
  def separator
@@ -16,6 +16,14 @@ module CSD
16
16
  $stdout.flush
17
17
  end
18
18
 
19
+ # Be careful, this function writes to +STDOUT+ and not to <tt>$stdout</tt>. In other words,
20
+ # the output cannot be hidden from the end-user, and thus, for example, not be properly
21
+ # tested in the test suite. ask_yes_no is provided by Gem::UserInteraction.
22
+ #
23
+ def continue?
24
+ ask_yes_no("Continue?".red.bold, true)
25
+ end
26
+
19
27
  def debug(message)
20
28
  $stdout.puts "DEBUG: #{message}".magenta if Options.debug
21
29
  end
@@ -10,16 +10,19 @@ module CSD
10
10
 
11
11
  def indicate_activity
12
12
  end
13
-
13
+
14
+ def continue?
15
+ end
16
+
14
17
  def debug(message)
15
18
  end
16
-
19
+
17
20
  def info(message)
18
21
  end
19
-
22
+
20
23
  def warn(message)
21
24
  end
22
-
25
+
23
26
  def error(message)
24
27
  end
25
28
 
@@ -1,4 +1,8 @@
1
1
  # -*- encoding: UTF-8 -*-
2
+ require 'test/unit/assertions'
3
+
4
+ # This module is part of the Zentest framework released under the MIT license.
5
+ # It comprises extra assertions for Test::Unit
2
6
  #
3
7
  # (The MIT License)
4
8
  #
@@ -22,41 +26,41 @@
22
26
  # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
27
  # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
28
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
+ #
30
+ module Test #:nodoc:
31
+ module Unit #:nodoc:
32
+ module Assertions #:nodoc:
33
+
34
+ # Captures $stdout and $stderr to StringIO objects and returns them.
35
+ # Restores $stdout and $stderr when done.
36
+ #
37
+ # Usage:
38
+ # def test_puts
39
+ # out, err = capture do
40
+ # puts 'hi'
41
+ # STDERR.puts 'bye!'
42
+ # end
43
+ # assert_equal "hi\n", out.string
44
+ # assert_equal "bye!\n", err.string
45
+ # end
46
+ #
47
+ def capture
48
+ require 'stringio'
49
+ orig_stdout = $stdout.dup
50
+ orig_stderr = $stderr.dup
51
+ captured_stdout = StringIO.new
52
+ captured_stderr = StringIO.new
53
+ $stdout = captured_stdout
54
+ $stderr = captured_stderr
55
+ yield
56
+ captured_stdout.rewind
57
+ captured_stderr.rewind
58
+ return captured_stdout.string, captured_stderr.string
59
+ ensure
60
+ $stdout = orig_stdout
61
+ $stderr = orig_stderr
62
+ end
25
63
 
26
- require 'test/unit/assertions'
27
-
28
- # Extra assertions for Test::Unit
29
-
30
- module Test::Unit::Assertions
31
-
32
- # Captures $stdout and $stderr to StringIO objects and returns them.
33
- # Restores $stdout and $stderr when done.
34
- #
35
- # Usage:
36
- # def test_puts
37
- # out, err = capture do
38
- # puts 'hi'
39
- # STDERR.puts 'bye!'
40
- # end
41
- # assert_equal "hi\n", out.string
42
- # assert_equal "bye!\n", err.string
43
- # end
44
- #
45
- def capture
46
- require 'stringio'
47
- orig_stdout = $stdout.dup
48
- orig_stderr = $stderr.dup
49
- captured_stdout = StringIO.new
50
- captured_stderr = StringIO.new
51
- $stdout = captured_stdout
52
- $stderr = captured_stderr
53
- yield
54
- captured_stdout.rewind
55
- captured_stderr.rewind
56
- return captured_stdout.string, captured_stderr.string
57
- ensure
58
- $stdout = orig_stdout
59
- $stderr = orig_stderr
64
+ end
60
65
  end
61
-
62
66
  end