scide 0.0.5 → 0.0.6
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.
- data/VERSION +1 -1
- data/lib/scide/command.rb +94 -39
- data/lib/scide/commands/edit.rb +27 -3
- data/lib/scide/commands/run.rb +16 -3
- data/lib/scide/commands/show.rb +22 -1
- data/lib/scide/commands/tail.rb +27 -3
- data/lib/scide/config.rb +49 -19
- data/lib/scide/global.rb +18 -3
- data/lib/scide/opts.rb +7 -0
- data/lib/scide/overmind.rb +28 -4
- data/lib/scide/project.rb +46 -11
- data/lib/scide/screen.rb +50 -16
- data/lib/scide/window.rb +55 -10
- data/lib/scide.rb +57 -9
- data/scide.gemspec +7 -2
- data/spec/command_spec.rb +87 -0
- data/spec/commands/edit_spec.rb +19 -0
- data/spec/commands/run_spec.rb +9 -0
- data/spec/commands/show_spec.rb +15 -0
- data/spec/commands/tail_spec.rb +14 -0
- metadata +22 -17
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/lib/scide/command.rb
CHANGED
@@ -1,69 +1,124 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# A command to be used in a GNU Screen window. There are several
|
4
|
+
# command implementations (show command, run command, tail file, etc).
|
5
|
+
# See under Scide::Commands.
|
3
6
|
class Command
|
4
7
|
|
5
|
-
|
8
|
+
# The options given to this command. These are built by merging
|
9
|
+
# global options, project options and window options.
|
10
|
+
attr_reader :options
|
6
11
|
|
12
|
+
# Returns a new command for the given window.
|
13
|
+
#
|
14
|
+
# ==== Arguments
|
15
|
+
# * <tt>window</tt> - The window in which the command will be used.
|
16
|
+
# Command options are retrieved from Scide::Window#options. See
|
17
|
+
# #initialize.
|
18
|
+
# * <tt>contents</tt> - The command configuration (String or Hash).
|
19
|
+
#
|
20
|
+
# ==== String Initialization
|
21
|
+
# The string must be in the format <tt>COMMAND [CONTENTS]</tt>.
|
22
|
+
#
|
23
|
+
# <tt>TYPE</tt> is the name of the command class under
|
24
|
+
# Scide::Commands, in uppercase camelcase. For example, <tt>TAIL</tt>
|
25
|
+
# corresponds to Scide::Commands::Tail, <tt>MY_COMMAND</tt> would
|
26
|
+
# correspond to Scide::Commands::MyCommand.
|
27
|
+
#
|
28
|
+
# <tt>CONTENTS</tt> is the contents of the command.
|
29
|
+
#
|
30
|
+
# ==== Hash Initialization
|
31
|
+
# The following options can be given:
|
32
|
+
# * <tt>:command => string</tt> is the same <tt>COMMAND</tt> as
|
33
|
+
# for string initialization above.
|
34
|
+
# * <tt>:contents => string or other</tt> is the same <tt>CONTENTS</tt>
|
35
|
+
# as for string initialization above. Typically this is only a
|
36
|
+
# string, but more advanced commands might be initialized with
|
37
|
+
# arrays or hashes.
|
38
|
+
def self.resolve window, contents
|
7
39
|
if contents.kind_of? Hash
|
8
|
-
|
9
|
-
properties = properties.merge contents[:properties] if contents.key? :properties
|
10
|
-
end
|
11
|
-
|
12
|
-
klass, contents = if contents.kind_of? Hash
|
13
|
-
resolve_from_hash contents, properties, options
|
40
|
+
resolve_from_hash window, contents
|
14
41
|
elsif contents.kind_of? String
|
15
|
-
resolve_from_string
|
42
|
+
resolve_from_string window, contents
|
43
|
+
else
|
44
|
+
raise ArgumentError, 'command must be a string or a hash'
|
16
45
|
end
|
17
|
-
|
18
|
-
klass.new contents, properties, build_options(options, klass)
|
19
46
|
end
|
20
47
|
|
21
|
-
|
22
|
-
|
23
|
-
|
48
|
+
# Returns a new command with the given options.
|
49
|
+
#
|
50
|
+
# ==== Arguments
|
51
|
+
# * <tt>contents</tt> - The contents of the command. Typically this
|
52
|
+
# is only a string, but more advanced commands might be initialized
|
53
|
+
# with arrays or hashes. By default, the contents can be retrieved
|
54
|
+
# as a string with #text_with_options.
|
55
|
+
# * <tt>options</tt> - Options that can be used in the string contents
|
56
|
+
# of the command. See #text_with_options.
|
57
|
+
def initialize contents, options = {}
|
58
|
+
|
59
|
+
# fill text only if it's not already there, in case a subclass does
|
60
|
+
# some initialization work before calling super
|
61
|
+
@text ||= contents.to_s
|
62
|
+
|
63
|
+
# merge given options to the already initialized ones, if any
|
64
|
+
@options = (@options || {}).merge options
|
24
65
|
end
|
25
66
|
|
67
|
+
# Returns a representation of this command as a GNU Screen
|
68
|
+
# configuration fragment.
|
69
|
+
#
|
70
|
+
# This default implementation raises an error and must be
|
71
|
+
# overriden by subclasses.
|
26
72
|
def to_screen
|
27
73
|
raise 'Use a subclass'
|
28
74
|
end
|
29
75
|
|
30
|
-
|
31
|
-
|
76
|
+
# Returns the text of this command with filtered option placeholders.
|
77
|
+
#
|
78
|
+
# ==== Examples
|
79
|
+
# com_text = 'tail %{tail} -f file.txt -c %{foo}'
|
80
|
+
# com = Scide::Command.new com_text, :tail => '-n 1000', :foo => 400
|
81
|
+
#
|
82
|
+
# com.text_with_options #=> 'tail -n 1000 -f file.txt -c 400'
|
83
|
+
def text_with_options
|
84
|
+
@text.dup.tap do |s|
|
85
|
+
@options.each_pair do |key, value|
|
86
|
+
s.gsub! /\%\{#{Regexp.escape key}\}/, value.to_s
|
87
|
+
end
|
88
|
+
end
|
32
89
|
end
|
33
90
|
|
34
91
|
private
|
35
92
|
|
36
|
-
|
37
|
-
|
38
|
-
|
93
|
+
# Returns a new command for the given window. The given
|
94
|
+
# contents are a hash. See Scide::Command.resolve.
|
95
|
+
def self.resolve_from_hash window, contents
|
96
|
+
begin
|
97
|
+
klass = Scide::Commands.const_get contents[:command].downcase.camelize
|
98
|
+
klass.new contents[:contents], window.options.dup
|
99
|
+
rescue NameError => err
|
100
|
+
raise ArgumentError, "unknown '#{contents[:command]}' command type"
|
101
|
+
end
|
39
102
|
end
|
40
103
|
|
41
|
-
|
104
|
+
# Returns a new command for the given window. The given
|
105
|
+
# contents are a string. See Scide::Command.resolve.
|
106
|
+
def self.resolve_from_string window, contents
|
42
107
|
klass_name, text = contents.split /\s+/, 2
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
klass_name = klass.name.demodulize.downcase
|
49
|
-
current_options = options.try(:[], klass_name)
|
50
|
-
current_klass = klass
|
51
|
-
while current_klass != Scide::Command and current_options.blank?
|
52
|
-
current_klass = current_klass.superclass
|
53
|
-
current_options = options.try(:[], current_klass.name.demodulize.downcase)
|
108
|
+
begin
|
109
|
+
klass = Scide::Commands.const_get klass_name.downcase.camelize
|
110
|
+
klass.new text, window.options.dup
|
111
|
+
rescue NameError => err
|
112
|
+
raise ArgumentError, "unknown '#{klass_name}' command type"
|
54
113
|
end
|
55
|
-
current_options
|
56
114
|
end
|
115
|
+
end
|
57
116
|
|
58
|
-
|
59
|
-
|
60
|
-
@properties.each_pair do |key, value|
|
61
|
-
s.gsub! /\%\{#{key}\}/, value
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
117
|
+
# Module containing scide command classes.
|
118
|
+
module Commands
|
65
119
|
end
|
66
120
|
end
|
67
121
|
|
122
|
+
# load pre-defined commands
|
68
123
|
deps_dir = File.join File.dirname(__FILE__), 'commands'
|
69
|
-
%w( run tail
|
124
|
+
%w( show run tail edit ).each{ |dep| require File.join(deps_dir, dep) }
|
data/lib/scide/commands/edit.rb
CHANGED
@@ -2,11 +2,35 @@ module Scide
|
|
2
2
|
|
3
3
|
module Commands
|
4
4
|
|
5
|
+
# Edits a file with the default editor (<tt>$EDITOR</tt>).
|
6
|
+
#
|
7
|
+
# ==== Configuration Example
|
8
|
+
# # this YAML configuration,
|
9
|
+
# projects:
|
10
|
+
# project1:
|
11
|
+
# options:
|
12
|
+
# edit: '-c MyVimCommand'
|
13
|
+
# windows:
|
14
|
+
# - "window1 EDIT $HOME/fubar.txt"
|
15
|
+
#
|
16
|
+
# # will produce the following command in window1:
|
17
|
+
# $EDITOR -c MyVimCommand $HOME/fubar.txt
|
5
18
|
class Edit < Scide::Commands::Run
|
6
19
|
|
7
|
-
|
8
|
-
|
9
|
-
|
20
|
+
# Returns a new edit command.
|
21
|
+
#
|
22
|
+
# See class definition for examples.
|
23
|
+
#
|
24
|
+
# ==== Arguments
|
25
|
+
# * <tt>contents</tt> - The file to edit.
|
26
|
+
# * <tt>options</tt> - Options that can be used in the contents
|
27
|
+
# of the command.
|
28
|
+
#
|
29
|
+
# ==== Options
|
30
|
+
# * <tt>:edit => string</tt> - Arguments to the editor.
|
31
|
+
def initialize contents, options = {}
|
32
|
+
super contents, options
|
33
|
+
@text = [ '$EDITOR', options[:edit].to_s, @text.to_s ].select(&:present?).join(' ')
|
10
34
|
end
|
11
35
|
end
|
12
36
|
end
|
data/lib/scide/commands/run.rb
CHANGED
@@ -2,10 +2,23 @@ module Scide
|
|
2
2
|
|
3
3
|
module Commands
|
4
4
|
|
5
|
-
|
5
|
+
# Runs a command.
|
6
|
+
#
|
7
|
+
# ==== Configuration Example
|
8
|
+
# # this YAML configuration,
|
9
|
+
# projects:
|
10
|
+
# project1:
|
11
|
+
# windows:
|
12
|
+
# - "window1 RUN rails server"
|
13
|
+
#
|
14
|
+
# # will produce the following command in window1:
|
15
|
+
# rails server
|
16
|
+
class Run < Scide::Commands::Show
|
6
17
|
|
7
|
-
|
8
|
-
|
18
|
+
# Appends a carriage return to the command so that
|
19
|
+
# it will not only be shown but also executed.
|
20
|
+
def text_with_options
|
21
|
+
"#{super}\\012"
|
9
22
|
end
|
10
23
|
end
|
11
24
|
end
|
data/lib/scide/commands/show.rb
CHANGED
@@ -2,10 +2,31 @@ module Scide
|
|
2
2
|
|
3
3
|
module Commands
|
4
4
|
|
5
|
+
# Prepares and shows a command but do not run it.
|
6
|
+
#
|
7
|
+
# ==== Configuration Example
|
8
|
+
# # this YAML configuration,
|
9
|
+
# projects:
|
10
|
+
# project1:
|
11
|
+
# options:
|
12
|
+
# host: 127.0.0.1
|
13
|
+
# windows:
|
14
|
+
# - "window1 SHOW ssh %{host}"
|
15
|
+
#
|
16
|
+
# # will produce the following command in window1:
|
17
|
+
# ssh 127.0.0.1
|
5
18
|
class Show < Scide::Command
|
6
19
|
|
20
|
+
def initialize contents, options = {}
|
21
|
+
super contents, options
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a configuration fragment that will put
|
25
|
+
# this command GNU \Screen window without running it.
|
26
|
+
# This will use screen's <tt>stuff</tt> command to
|
27
|
+
# put the text in the window.
|
7
28
|
def to_screen
|
8
|
-
%|stuff "#{
|
29
|
+
%|stuff "#{text_with_options}"|
|
9
30
|
end
|
10
31
|
end
|
11
32
|
end
|
data/lib/scide/commands/tail.rb
CHANGED
@@ -2,11 +2,35 @@ module Scide
|
|
2
2
|
|
3
3
|
module Commands
|
4
4
|
|
5
|
+
# Tails a file.
|
6
|
+
#
|
7
|
+
# ==== Configuration Example
|
8
|
+
# # this YAML configuration,
|
9
|
+
# projects:
|
10
|
+
# project1:
|
11
|
+
# options:
|
12
|
+
# tail: '-n 1000'
|
13
|
+
# windows:
|
14
|
+
# - "window1 TAIL $HOME/fubar.txt"
|
15
|
+
#
|
16
|
+
# # will produce the following command in window1:
|
17
|
+
# tail -n 1000 -f $HOME/fubar.txt
|
5
18
|
class Tail < Scide::Commands::Run
|
6
19
|
|
7
|
-
|
8
|
-
|
9
|
-
|
20
|
+
# Returns a new tail command.
|
21
|
+
#
|
22
|
+
# See class definition for examples.
|
23
|
+
#
|
24
|
+
# ==== Arguments
|
25
|
+
# * <tt>contents</tt> - The file to tail.
|
26
|
+
# * <tt>options</tt> - Options that can be used in the
|
27
|
+
# contents of the command.
|
28
|
+
#
|
29
|
+
# ==== Options
|
30
|
+
# * <tt>tail => string</tt> - Arguments to tail.
|
31
|
+
def initialize contents, options = {}
|
32
|
+
super contents, options
|
33
|
+
@text = [ 'tail', options[:tail].to_s, '-f', @text.to_s ].select(&:present?).join(' ')
|
10
34
|
end
|
11
35
|
end
|
12
36
|
end
|
data/lib/scide/config.rb
CHANGED
@@ -1,18 +1,47 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
|
-
CONFIG_FILE = File.join File.expand_path('~'), '.scide', 'config.yml'
|
4
|
-
|
5
3
|
module Scide
|
6
4
|
|
5
|
+
# Complete scide configuration as an object graph.
|
7
6
|
class Config
|
7
|
+
|
8
|
+
# The file from which the configuration is normally loaded.
|
9
|
+
# This defaults to <tt>$HOME/.scide/config.yml</tt>.
|
10
|
+
DEFAULT_CONFIG_FILE = File.join File.expand_path('~'), '.scide', 'config.yml'
|
11
|
+
|
12
|
+
# The file from which this configuration will be loaded.
|
8
13
|
attr_accessor :file
|
9
|
-
|
14
|
+
|
15
|
+
# GNU Screen options. Accessible after calling #load!.
|
16
|
+
attr_reader :screen
|
10
17
|
|
18
|
+
# The global configuration. Accessible after calling #load!.
|
19
|
+
attr_reader :global
|
20
|
+
|
21
|
+
# The project definitions (windows, option overrides, etc). Accessible
|
22
|
+
# after calling #load!.
|
23
|
+
attr_reader :projects
|
24
|
+
|
25
|
+
# Returns an empty configuration.
|
26
|
+
#
|
27
|
+
# ==== Arguments
|
28
|
+
# * <tt>file</tt> - The file from which to load the configuration. If not
|
29
|
+
# given, this defaults to DEFAULT_CONFIG_FILE.
|
11
30
|
def initialize file = nil
|
12
|
-
@file = file.try(:to_s) ||
|
31
|
+
@file = file.try(:to_s) || DEFAULT_CONFIG_FILE
|
13
32
|
end
|
14
33
|
|
15
|
-
|
34
|
+
# Loads this configuration. This will read from #file and parse the contents
|
35
|
+
# as YAML. Configuration elements can then be retrieved with #global,
|
36
|
+
# #projects and #screen.
|
37
|
+
#
|
38
|
+
# ==== Errors
|
39
|
+
# * <tt>config_not_found</tt> - #file does not exist.
|
40
|
+
# * <tt>config_not_readable</tt> - #file cannot be read by the user running scide.
|
41
|
+
# * <tt>malformed_config</tt> - #file contains malformed YAML.
|
42
|
+
# * <tt>invalid_config</tt> - #file contains invalid configuration (see README).
|
43
|
+
# * <tt>unexpected</tt> - #file could not be read.
|
44
|
+
def load!
|
16
45
|
|
17
46
|
Scide.fail :config_not_found, "ERROR: expected to find configuration at #{@file}" unless File.exists? @file
|
18
47
|
Scide.fail :config_not_readable, "ERROR: configuration #{@file} is not readable" unless File.readable? @file
|
@@ -34,26 +63,27 @@ module Scide
|
|
34
63
|
# laziness
|
35
64
|
@config = HashWithIndifferentAccess.new @config
|
36
65
|
|
66
|
+
invalid_config 'screen configuration must be a hash' unless @config[:screen].nil? or @config[:screen].kind_of?(Hash)
|
67
|
+
invalid_config 'projects configuration must be a hash' unless @config[:projects].nil? or @config[:projects].kind_of?(Hash)
|
68
|
+
|
37
69
|
begin
|
38
|
-
|
39
|
-
|
70
|
+
@screen = @config[:screen]
|
71
|
+
@global = Scide::Global.new @config[:global]
|
72
|
+
@projects = @config[:projects].inject(HashWithIndifferentAccess.new) do |memo,obj|
|
73
|
+
memo[obj[0]] = Scide::Project.new @global, obj[0], obj[1]; memo
|
74
|
+
end
|
75
|
+
rescue ArgumentError => err
|
40
76
|
invalid_config err
|
41
77
|
end
|
42
|
-
|
43
|
-
@global = Scide::Global.new @config[:global]
|
44
|
-
@screen = @config[:screen]
|
45
|
-
@projects = @config[:projects].inject(HashWithIndifferentAccess.new) do |memo,obj|
|
46
|
-
memo[obj[0].to_sym] = Scide::Project.new obj[1], obj[0], @global; memo
|
47
|
-
end
|
48
78
|
end
|
49
79
|
|
50
|
-
|
51
|
-
raise 'global configuration must be a hash' if @config[:global] and !@config[:global].kind_of?(Hash)
|
52
|
-
raise 'configuration must contain a hash of projects' unless @config[:projects].kind_of? Hash
|
53
|
-
end
|
80
|
+
private
|
54
81
|
|
55
|
-
|
56
|
-
|
82
|
+
# Causes scide to fail with an <tt>invalid_config</tt> error (see Scide#fail).
|
83
|
+
# Builds a complete error message containing the full path to the
|
84
|
+
# configuration file and the given message.
|
85
|
+
def invalid_config msg
|
86
|
+
Scide.fail :invalid_config, "ERROR: configuration #{@file} is invalid.\n #{msg}"
|
57
87
|
end
|
58
88
|
end
|
59
89
|
end
|
data/lib/scide/global.rb
CHANGED
@@ -1,13 +1,28 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# Global scide options (base path for all projects,
|
4
|
+
# shared options).
|
3
5
|
class Global
|
4
|
-
|
6
|
+
|
7
|
+
# The path under which all projects reside by default.
|
8
|
+
# (Can be overriden at the project level.)
|
9
|
+
attr_reader :path
|
10
|
+
|
11
|
+
# Global options shared by all projects.
|
12
|
+
attr_reader :options
|
5
13
|
|
14
|
+
# Builds global options.
|
15
|
+
#
|
16
|
+
# ==== Arguments
|
17
|
+
# * <tt>contents</tt> - The global options hash.
|
6
18
|
def initialize contents
|
7
|
-
|
8
|
-
|
19
|
+
raise ArgumentError, 'global configuration must be a hash' unless contents.kind_of? Hash
|
20
|
+
|
21
|
+
@options = contents[:options] || {}
|
9
22
|
|
23
|
+
# default to home directory
|
10
24
|
@path = contents[:path].try(:to_s) || File.expand_path('~')
|
25
|
+
# expand from home directory unless absolute
|
11
26
|
@path = File.join File.expand_path('~'), @path unless @path.match /^\//
|
12
27
|
end
|
13
28
|
end
|
data/lib/scide/opts.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# Pre-configured scide option parser.
|
3
4
|
class Opts < Upoj::Opts
|
4
5
|
|
6
|
+
# Returns the scide option parser. Run scide with <tt>--usage</tt>
|
7
|
+
# to see available options.
|
5
8
|
def initialize
|
6
9
|
super({
|
7
10
|
:banner => {
|
@@ -17,6 +20,10 @@ module Scide
|
|
17
20
|
help!.usage!
|
18
21
|
end
|
19
22
|
|
23
|
+
# Parses the given arguments.
|
24
|
+
#
|
25
|
+
# Causes scide to fail with an <tt>invalid_argument</tt> error (see Scide#fail)
|
26
|
+
# if an argument is invalid.
|
20
27
|
def parse! args
|
21
28
|
begin
|
22
29
|
super args
|
data/lib/scide/overmind.rb
CHANGED
@@ -1,27 +1,51 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# Utility class to run scide in a script.
|
3
4
|
class Overmind
|
4
5
|
|
6
|
+
# Awakens the overmind.
|
5
7
|
def initialize
|
6
8
|
@cli = Scide::Opts.new
|
7
9
|
@config = Scide::Config.new
|
8
10
|
end
|
9
11
|
|
12
|
+
# Parses command-line arguments and loads the configuration file.
|
13
|
+
# Any error will be run through Scide.fail.
|
10
14
|
def brood
|
11
15
|
@cli.parse! ARGV
|
12
16
|
@config.file = @cli.funnel[:config] if @cli.funnel.key? :config
|
13
|
-
@config.load
|
17
|
+
@config.load!
|
14
18
|
@initialized = true
|
15
19
|
self
|
16
20
|
end
|
17
21
|
|
22
|
+
# Runs GNU \Screen with the project given as argument.
|
23
|
+
# The <tt>--dry-run</tt> option will cause scide to print the
|
24
|
+
# resulting configuration instead of running it.
|
25
|
+
#
|
26
|
+
# ==== Errors
|
27
|
+
# * <tt>not_initialized</tt> - If #brood was not called.
|
28
|
+
# * <tt>unknown_project</tt> - If the given project is not found
|
29
|
+
# in the configuration file.
|
30
|
+
# * <tt>screen_not_found</tt> - If the GNU \Screen binary is not
|
31
|
+
# found with <tt>which</tt>.
|
18
32
|
def dominate
|
19
33
|
|
20
|
-
Scide.fail :not_initialized, 'ERROR: call #brood to initialize' unless @initialized
|
34
|
+
Scide.fail :not_initialized, 'ERROR: call #brood to initialize.' unless @initialized
|
21
35
|
|
22
36
|
project_key = ARGV.shift
|
23
|
-
|
24
|
-
|
37
|
+
|
38
|
+
if project_key.blank?
|
39
|
+
available_projects = @config.projects.keys.join(', ')
|
40
|
+
Scide.fail :invalid_argument, "You must choose a project. Available projects: #{available_projects}."
|
41
|
+
end
|
42
|
+
|
43
|
+
unless @config.projects.key? project_key
|
44
|
+
Scide.fail :unknown_project, "ERROR: there is no project '#{project_key}' in configuration #{@config.file}."
|
45
|
+
end
|
46
|
+
|
47
|
+
screen = Scide::Screen.new @config.projects[project_key], @config.screen
|
48
|
+
screen.check_binary
|
25
49
|
|
26
50
|
if @cli.funnel[:'dry-run']
|
27
51
|
puts
|
data/lib/scide/project.rb
CHANGED
@@ -1,29 +1,64 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# Scide configuration for one project.
|
3
4
|
class Project
|
4
|
-
attr_accessor :properties, :options, :path
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
# The project key in the projects configuration hash.
|
7
|
+
attr_reader :key
|
8
8
|
|
9
|
+
# The path where the project is located. See #initialize.
|
10
|
+
attr_reader :path
|
11
|
+
|
12
|
+
# Project-specific options. Can be used by commands. See #initialize.
|
13
|
+
attr_reader :options
|
14
|
+
|
15
|
+
# Returns a project configuration.
|
16
|
+
#
|
17
|
+
# If not given in the project hash, #path is built by joining
|
18
|
+
# the global path and <tt>key</tt>.
|
19
|
+
#
|
20
|
+
# ==== Arguments
|
21
|
+
# * <tt>global</tt> - The global configuration.
|
22
|
+
# * <tt>key</tt> - The key identifying the project. This is the
|
23
|
+
# key in the projects hash.
|
24
|
+
# * <tt>contents</tt> - The project hash.
|
25
|
+
#
|
26
|
+
# ==== Project Options
|
27
|
+
#
|
28
|
+
# #options is built by merging the options given in the project
|
29
|
+
# hash with the global options.
|
30
|
+
#
|
31
|
+
# The following default options are added if not given:
|
32
|
+
# * <tt>name</tt> - Defaults to the project key.
|
33
|
+
# * <tt>path</tt> - The path where the project is located.
|
34
|
+
def initialize global, key, contents
|
35
|
+
raise ArgumentError, "project '#{key}' must be a hash" unless contents.kind_of? Hash
|
36
|
+
raise ArgumentError, "windows of project '#{key}' must be an array" unless contents[:windows].nil? or contents[:windows].kind_of?(Array)
|
37
|
+
raise ArgumentError, "options of project '#{key}' must be a hash" unless contents[:options].nil? or contents[:options].kind_of?(Hash)
|
38
|
+
|
39
|
+
@global, @key = global, key
|
40
|
+
|
41
|
+
# path defaults to project key
|
9
42
|
@path = contents[:path].try(:to_s) || key.to_s
|
43
|
+
# expand from home directory if not absolute
|
10
44
|
@path = File.join global.path, @path unless @path.match /^\//
|
11
45
|
|
12
|
-
@
|
13
|
-
@
|
14
|
-
|
15
|
-
@options = global.options.merge(contents[:options] || {})
|
46
|
+
@options = global.options.dup.merge(contents[:options] || {})
|
47
|
+
@options[:name] ||= key
|
48
|
+
@options[:path] ||= @path
|
16
49
|
|
17
|
-
@windows = []
|
18
|
-
contents[:windows].each do |w|
|
19
|
-
@windows << Scide::Window.new(w, self)
|
20
|
-
end
|
50
|
+
@windows = contents[:windows].collect{ |w| Scide::Window.new self, w }
|
21
51
|
end
|
22
52
|
|
53
|
+
# Returns a representation of this project as a GNU Screen
|
54
|
+
# configuration fragment. Returns nil if this project has
|
55
|
+
# no configured windows.
|
23
56
|
def to_screen
|
57
|
+
return nil if @windows.blank?
|
24
58
|
String.new.tap do |s|
|
25
59
|
@windows.each_with_index do |w,i|
|
26
60
|
s << w.to_screen(i)
|
61
|
+
s << "\n" if i != @windows.length - 1
|
27
62
|
end
|
28
63
|
end
|
29
64
|
end
|
data/lib/scide/screen.rb
CHANGED
@@ -1,57 +1,91 @@
|
|
1
1
|
require 'tempfile'
|
2
2
|
|
3
|
-
DEFAULT_HARDSTATUS = '%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'
|
4
|
-
|
5
3
|
module Scide
|
6
4
|
|
5
|
+
# Configuration of a GNU Screen session (windows for a specific project).
|
6
|
+
#
|
7
|
+
# The configuration will disable the startup message and display a hardstatus line.
|
8
|
+
# It will also display the windows of the given project.
|
7
9
|
class Screen
|
10
|
+
|
11
|
+
# The default screen hardstatus line.
|
12
|
+
DEFAULT_HARDSTATUS = '%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'
|
8
13
|
|
9
|
-
|
10
|
-
|
14
|
+
# Returns a screen configuration for the given project.
|
15
|
+
#
|
16
|
+
# ==== Arguments
|
17
|
+
# * <tt>project</tt> - The project.
|
18
|
+
# * <tt>options</tt> - Screen-specific options (see below).
|
19
|
+
#
|
20
|
+
# ==== Options
|
21
|
+
# * <tt>binary</tt> - Screen binary (defaults to <tt>screen</tt>).
|
22
|
+
# * <tt>args</tt> - Command-line arguments that will be given to screen (e.g. <tt>-U</tt> for unicode).
|
23
|
+
# * <tt>hardstatus</tt> - Hardstatus line configuration (defaults to #DEFAULT_HARDSTATUS).
|
24
|
+
def initialize project, options
|
25
|
+
raise ArgumentError, 'screen configuration must be a hash' unless options.nil? or options.kind_of?(Hash)
|
11
26
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
@project = config.projects[project_key]
|
27
|
+
@project = project
|
28
|
+
@options = options || {}
|
16
29
|
end
|
17
30
|
|
31
|
+
# Runs screen with this configuration.
|
32
|
+
#
|
33
|
+
# The configuration is saved to a temporary file, then removed.
|
18
34
|
def run
|
19
35
|
file = Tempfile.new 'scide'
|
20
|
-
save file
|
36
|
+
save file.path
|
21
37
|
system to_command(file.path)
|
22
38
|
file.unlink
|
23
39
|
end
|
24
40
|
|
41
|
+
# Returns the command that will be used to run screen with this configuration.
|
42
|
+
#
|
43
|
+
# ==== Arguments
|
44
|
+
# * <tt>tmp_file</tt> - The temporary file in which the configuration will be stored.
|
45
|
+
# (Optional for dry-run.)
|
25
46
|
def to_command tmp_file = 'TEMPORARY_FILE'
|
26
|
-
"cd #{@project.path} && #{binary} #{
|
47
|
+
"cd #{@project.path} && #{binary} #{args} -c #{tmp_file}"
|
27
48
|
end
|
28
49
|
|
29
|
-
|
50
|
+
# Verifies that the screen binary is there. If not, causes scide
|
51
|
+
# to fail with a <tt>screen_not_found</tt> error (see Scide#fail}.
|
52
|
+
def check_binary
|
30
53
|
Scide.fail :screen_not_found, "ERROR: #{binary} not found" unless system("which #{binary}", { [ :out, :err ] => :close })
|
31
54
|
end
|
32
55
|
|
56
|
+
# Returns a representation of this configuration as a string.
|
33
57
|
def to_s
|
34
58
|
String.new.tap do |s|
|
35
59
|
s << "startup_message off\n"
|
36
60
|
s << "hardstatus on\n"
|
37
61
|
s << "hardstatus alwayslastline\n"
|
38
|
-
s << "hardstatus string '#{
|
62
|
+
s << "hardstatus string '#{hardstatus}'\n\n"
|
39
63
|
s << @project.to_screen
|
40
64
|
end
|
41
65
|
end
|
42
66
|
|
43
67
|
private
|
44
68
|
|
69
|
+
# Returns the screen hardstatus line given as option, or
|
70
|
+
# the default #DEFAULT_HARDSTATUS.
|
71
|
+
def hardstatus
|
72
|
+
@options[:hardstatus] || DEFAULT_HARDSTATUS
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns the screen binary given as option, or the
|
76
|
+
# default (<tt>screen</tt>).
|
45
77
|
def binary
|
46
|
-
@
|
78
|
+
@options[:binary] || 'screen'
|
47
79
|
end
|
48
80
|
|
49
|
-
|
50
|
-
|
81
|
+
# Returns the screen command-line arguments given as options.
|
82
|
+
def args
|
83
|
+
@options[:args]
|
51
84
|
end
|
52
85
|
|
86
|
+
# Saves this configuration to the file at the given path.
|
53
87
|
def save file
|
54
|
-
File.open(file
|
88
|
+
File.open(file, 'w'){ |f| f.write to_s }
|
55
89
|
end
|
56
90
|
end
|
57
91
|
end
|
data/lib/scide/window.rb
CHANGED
@@ -1,35 +1,80 @@
|
|
1
1
|
module Scide
|
2
2
|
|
3
|
+
# Configuration of a GNU Screen window (name, command).
|
3
4
|
class Window
|
5
|
+
|
6
|
+
# Window-specific options. Can be used by commands. See #initialize.
|
7
|
+
attr_reader :options
|
4
8
|
|
5
|
-
|
9
|
+
# Returns a window for the given project.
|
10
|
+
#
|
11
|
+
# ==== Arguments
|
12
|
+
# * <tt>project</tt> - The project owning this window.
|
13
|
+
# * <tt>contents</tt> - The window configuration (String or Hash).
|
14
|
+
#
|
15
|
+
# ==== String Initialization
|
16
|
+
# The string must be in the format <tt>NAME [COMMAND]</tt> where
|
17
|
+
# <tt>NAME</tt> is the window name and <tt>COMMAND</tt> (optional)
|
18
|
+
# is the command configuration (see Scide::Command).
|
19
|
+
#
|
20
|
+
# ==== Hash Initialization
|
21
|
+
# The following options can be given:
|
22
|
+
# * <tt>:name => string</tt> - The window name.
|
23
|
+
# * <tt>:options => hash</tt> - Window-specific options (will be
|
24
|
+
# merged to the project options).
|
25
|
+
# * <tt>:command => string</tt> - The command to use for this window
|
26
|
+
# (will be built using Scide::Command#resolve).
|
27
|
+
# * <tt>:string => string</tt> - If given, <tt>:name</tt> and <tt>:command</tt>
|
28
|
+
# are ignored and string initialization will be performed with <tt>string</tt>.
|
29
|
+
# <tt>:options</tt> can still be used to override project options.
|
30
|
+
def initialize project, contents
|
6
31
|
@project = project
|
32
|
+
|
7
33
|
if contents.kind_of? Hash
|
8
|
-
init_from_hash contents
|
34
|
+
init_from_hash! contents
|
9
35
|
elsif contents.kind_of? String
|
10
|
-
init_from_string contents
|
36
|
+
init_from_string! contents
|
37
|
+
else
|
38
|
+
raise ArgumentError, "window '#{contents}' must be a string or a hash"
|
11
39
|
end
|
12
40
|
end
|
13
41
|
|
42
|
+
# Returns a representation of this window as a GNU Screen
|
43
|
+
# configuration frament.
|
44
|
+
#
|
45
|
+
# ==== Arguments
|
46
|
+
# * <tt>index</tt> - The position of the window (zero-based).
|
14
47
|
def to_screen index
|
15
48
|
String.new.tap do |s|
|
16
|
-
s << "screen -t #{@name} #{index}
|
17
|
-
s << @command.to_screen if @command
|
49
|
+
s << "screen -t #{@name} #{index}"
|
50
|
+
s << "\n#{@command.to_screen}" if @command
|
18
51
|
end
|
19
52
|
end
|
20
53
|
|
21
54
|
private
|
22
55
|
|
23
|
-
|
24
|
-
|
25
|
-
|
56
|
+
# Initializes this window from a hash. See #initialize for options.
|
57
|
+
def init_from_hash! contents
|
58
|
+
raise ArgumentError, "options of window '#{@name}' must be a hash" unless contents[:options].nil? or contents[:options].kind_of?(Hash)
|
59
|
+
@options = @project.options.dup.merge(contents[:options] || {})
|
60
|
+
|
61
|
+
if contents[:string].present?
|
62
|
+
init_from_string! contents[:string]
|
63
|
+
else
|
64
|
+
raise ArgumentError, "window '#{contents}' must have a name" unless contents[:name].present?
|
65
|
+
@name = contents[:name]
|
66
|
+
@command = Command.resolve self, contents if contents.key? :command
|
67
|
+
end
|
26
68
|
end
|
27
69
|
|
28
|
-
|
70
|
+
# Initializes this window from a string. See #initialize for format.
|
71
|
+
def init_from_string! contents
|
72
|
+
raise ArgumentError, "window '#{contents}' must not be an empty string" unless contents.present?
|
29
73
|
content_parts = contents.split /\s+/, 2
|
30
74
|
@name = content_parts[0]
|
75
|
+
@options ||= @project.options.dup
|
31
76
|
if content_parts.length == 2
|
32
|
-
@command = Command.resolve content_parts[1]
|
77
|
+
@command = Command.resolve self, content_parts[1]
|
33
78
|
end
|
34
79
|
end
|
35
80
|
end
|
data/lib/scide.rb
CHANGED
@@ -1,26 +1,74 @@
|
|
1
1
|
require 'paint'
|
2
2
|
require 'upoj-rb'
|
3
3
|
|
4
|
+
# Generator of GNU Screen configuration files.
|
4
5
|
module Scide
|
6
|
+
|
7
|
+
# Current version.
|
5
8
|
VERSION = File.open(File.join(File.dirname(__FILE__), '..', 'VERSION'), 'r').read
|
9
|
+
|
10
|
+
# Exit status codes.
|
11
|
+
#
|
12
|
+
# ==== Codes
|
13
|
+
# * <tt>unexpected</tt> - 1.
|
14
|
+
# * <tt>invalid_argument</tt> - 2.
|
15
|
+
# * <tt>not_initialized</tt> - 3.
|
16
|
+
# * <tt>screen_not_found</tt> - 4.
|
17
|
+
# * <tt>config_not_found</tt> - 10.
|
18
|
+
# * <tt>config_not_readable</tt> - 11.
|
19
|
+
# * <tt>malformed_config</tt> - 12.
|
20
|
+
# * <tt>invalid_config</tt> - 13.
|
21
|
+
# * <tt>unknown_project</tt> - 14.
|
6
22
|
EXIT = {
|
7
23
|
:unexpected => 1,
|
8
24
|
:invalid_argument => 2,
|
9
25
|
:not_initialized => 3,
|
10
26
|
:screen_not_found => 4,
|
11
|
-
:config_not_found =>
|
12
|
-
:config_not_readable =>
|
13
|
-
:malformed_config =>
|
14
|
-
:invalid_config =>
|
15
|
-
:unknown_project =>
|
27
|
+
:config_not_found => 10,
|
28
|
+
:config_not_readable => 11,
|
29
|
+
:malformed_config => 12,
|
30
|
+
:invalid_config => 13,
|
31
|
+
:unknown_project => 14
|
16
32
|
}
|
17
33
|
|
34
|
+
# Prints a message on <tt>stderr</tt> and exits.
|
35
|
+
# If #condition is a key from #EXIT, the corresponding value
|
36
|
+
# will be used as the exit code. Otherwise, scide exits with
|
37
|
+
# status 1.
|
18
38
|
def self.fail condition, msg
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
39
|
+
if @@exit_on_fail
|
40
|
+
puts
|
41
|
+
warn Paint[msg, :yellow]
|
42
|
+
puts
|
43
|
+
EXIT.key?(condition) ? exit(EXIT[condition]) : exit(1)
|
44
|
+
else
|
45
|
+
raise Scide::Error.new condition, msg
|
46
|
+
end
|
23
47
|
end
|
48
|
+
|
49
|
+
# By default, scide is meant to be used as a standalone script
|
50
|
+
# and exits if an error occurs. If <tt>exit_on_fail</tt> is
|
51
|
+
# false, a Scide::Error will be raised instead. Scide can then
|
52
|
+
# be used by another script.
|
53
|
+
def self.exit_on_fail= exit_on_fail
|
54
|
+
@@exit_on_fail = exit_on_fail
|
55
|
+
end
|
56
|
+
|
57
|
+
# Scide error. Can be raised if #exit_on_fail is set to false.
|
58
|
+
class Error < StandardError
|
59
|
+
attr_reader :condition
|
60
|
+
|
61
|
+
# Returns a new error.
|
62
|
+
def initialize condition, msg
|
63
|
+
super msg
|
64
|
+
@condition = condition
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
@@exit_on_fail = true
|
24
71
|
end
|
25
72
|
|
73
|
+
# load scide components
|
26
74
|
%w( command config global opts overmind project screen window ).each{ |dep| require File.join(File.dirname(__FILE__), 'scide', dep) }
|
data/scide.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "scide"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["AlphaHydrae"]
|
12
|
-
s.date = "2011-10-
|
12
|
+
s.date = "2011-10-02"
|
13
13
|
s.description = "Utility to generate GNU screen configuration files."
|
14
14
|
s.email = "hydrae.alpha@gmail.com"
|
15
15
|
s.executables = ["scide"]
|
@@ -42,6 +42,11 @@ Gem::Specification.new do |s|
|
|
42
42
|
"lib/scide/screen.rb",
|
43
43
|
"lib/scide/window.rb",
|
44
44
|
"scide.gemspec",
|
45
|
+
"spec/command_spec.rb",
|
46
|
+
"spec/commands/edit_spec.rb",
|
47
|
+
"spec/commands/run_spec.rb",
|
48
|
+
"spec/commands/show_spec.rb",
|
49
|
+
"spec/commands/tail_spec.rb",
|
45
50
|
"spec/helper.rb"
|
46
51
|
]
|
47
52
|
s.homepage = "http://github.com/AlphaHydrae/scide"
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Scide
|
4
|
+
module Commands
|
5
|
+
class FuBar < Scide::Commands::Show
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Scide::Command do
|
11
|
+
|
12
|
+
it "should be abstract" do
|
13
|
+
com = Scide::Command.new 'fubar'
|
14
|
+
lambda{ com.to_screen }.should raise_error(StandardError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should use given contents as text" do
|
18
|
+
com = Scide::Command.new 'fubar'
|
19
|
+
com.text_with_options.should == 'fubar'
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should take options" do
|
23
|
+
com = Scide::Command.new 'fubar %{foo} %{bar}', :foo => 1, :bar => 2
|
24
|
+
com.text_with_options.should == 'fubar 1 2'
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'Class' do
|
28
|
+
before :each do
|
29
|
+
@options = { :a => 1, :b => true }
|
30
|
+
@window = double('window')
|
31
|
+
@window.stub(:options){ @options }
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should resolve command with a string" do
|
35
|
+
com = Scide::Command.resolve @window, 'SHOW fubar'
|
36
|
+
com.should be_a_kind_of(Scide::Commands::Show)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should use second part of string as contents when resolving a command with a string" do
|
40
|
+
com = Scide::Command.resolve @window, 'SHOW fubar'
|
41
|
+
com.text_with_options.should == 'fubar'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should resolve command with a hash" do
|
45
|
+
com = Scide::Command.resolve @window, :command => 'SHOW', :contents => 'fubar'
|
46
|
+
com.should be_a_kind_of(Scide::Commands::Show)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should give duplicated window options to the resolved string command" do
|
50
|
+
@window.should_receive :options
|
51
|
+
com = Scide::Command.resolve @window, 'SHOW fubar'
|
52
|
+
com.options.should == @options
|
53
|
+
com.options.should_not equal(@options)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should give duplicated window options to the resolved hash command" do
|
57
|
+
@window.should_receive :options
|
58
|
+
com = Scide::Command.resolve @window, :command => 'SHOW', :contents => 'fubar'
|
59
|
+
com.options.should == @options
|
60
|
+
com.options.should_not equal(@options)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should resolve camel-case command class names with a string" do
|
64
|
+
puts Scide::Commands::FuBar
|
65
|
+
com = Scide::Command.resolve @window, 'FU_BAR'
|
66
|
+
com.should be_a_kind_of(Scide::Commands::FuBar)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should resolve camel-case command class names with a hash" do
|
70
|
+
com = Scide::Command.resolve @window, :command => 'FU_BAR'
|
71
|
+
com.should be_a_kind_of(Scide::Commands::FuBar)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should raise an error when type of contents is unknown" do
|
75
|
+
lambda{ Scide::Command.resolve(@window, []) }.should raise_error(ArgumentError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should raise an error when trying to resolve a blank string" do
|
79
|
+
lambda{ Scide::Command.resolve(@window, ' ') }.should raise_error(ArgumentError)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should raise an error when trying to resolve an unknown command" do
|
83
|
+
lambda{ Scide::Command.resolve(@window, 'SHW fubar') }.should raise_error(ArgumentError)
|
84
|
+
lambda{ Scide::Command.resolve(@window, :command => 'SHW', :contents => 'fubar') }.should raise_error(ArgumentError)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Scide::Commands::Edit do
|
4
|
+
|
5
|
+
it "should use the preferred editor" do
|
6
|
+
com = Scide::Commands::Edit.new nil
|
7
|
+
com.text_with_options.should == '$EDITOR\012'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use given contents as arguments to the editor" do
|
11
|
+
com = Scide::Commands::Edit.new 'fubar'
|
12
|
+
com.text_with_options.should == '$EDITOR fubar\012'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should use the :edit option as arguments to the editor" do
|
16
|
+
com = Scide::Commands::Edit.new 'fubar', :edit => '-c MyCommand'
|
17
|
+
com.text_with_options.should == '$EDITOR -c MyCommand fubar\012'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Scide::Commands::Show do
|
4
|
+
|
5
|
+
it "should produce a GNU Screen stuff command" do
|
6
|
+
com = Scide::Commands::Show.new 'fubar'
|
7
|
+
com.to_screen.should == 'stuff "fubar"'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use #text_with_options as argument to stuff" do
|
11
|
+
com = Scide::Commands::Show.new 'fubar'
|
12
|
+
text_with_options = com.text_with_options
|
13
|
+
com.to_screen.should == %|stuff "#{text_with_options}"|
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Scide::Commands::Tail do
|
4
|
+
|
5
|
+
it "should use given contents as argument -f of tail" do
|
6
|
+
com = Scide::Commands::Tail.new 'fubar'
|
7
|
+
com.text_with_options.should == 'tail -f fubar\012'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use the :tail option as arguments to tail" do
|
11
|
+
com = Scide::Commands::Tail.new 'fubar', :tail => '-n 1000'
|
12
|
+
com.text_with_options.should == 'tail -n 1000 -f fubar\012'
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scide
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
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: 2011-10-
|
12
|
+
date: 2011-10-02 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: upoj-rb
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156558600 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.0.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156558600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &2156558080 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2156558080
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: shoulda
|
38
|
-
requirement: &
|
38
|
+
requirement: &2156557480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2156557480
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
requirement: &
|
49
|
+
requirement: &2156556880 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.0.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2156556880
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: jeweler
|
60
|
-
requirement: &
|
60
|
+
requirement: &2156556280 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.6.4
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2156556280
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rcov
|
71
|
-
requirement: &
|
71
|
+
requirement: &2156555680 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *2156555680
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rdoc
|
82
|
-
requirement: &
|
82
|
+
requirement: &2156555080 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *2156555080
|
91
91
|
description: Utility to generate GNU screen configuration files.
|
92
92
|
email: hydrae.alpha@gmail.com
|
93
93
|
executables:
|
@@ -121,6 +121,11 @@ files:
|
|
121
121
|
- lib/scide/screen.rb
|
122
122
|
- lib/scide/window.rb
|
123
123
|
- scide.gemspec
|
124
|
+
- spec/command_spec.rb
|
125
|
+
- spec/commands/edit_spec.rb
|
126
|
+
- spec/commands/run_spec.rb
|
127
|
+
- spec/commands/show_spec.rb
|
128
|
+
- spec/commands/tail_spec.rb
|
124
129
|
- spec/helper.rb
|
125
130
|
homepage: http://github.com/AlphaHydrae/scide
|
126
131
|
licenses:
|
@@ -137,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
142
|
version: '0'
|
138
143
|
segments:
|
139
144
|
- 0
|
140
|
-
hash:
|
145
|
+
hash: 1145488263121204374
|
141
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
147
|
none: false
|
143
148
|
requirements:
|