shell_utils 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/filename.rb +61 -0
- data/lib/session_zipper.rb +19 -0
- data/lib/shell_argument_exception.rb +9 -0
- data/lib/shell_process.rb +5 -0
- data/lib/shell_wrapper.rb +161 -0
- data/spec/filename_spec.rb +69 -0
- data/spec/shell_wrapper_spec.rb +61 -0
- metadata +82 -0
data/lib/filename.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
class Filename
|
2
|
+
|
3
|
+
DIR_SEPARATOR = '/'
|
4
|
+
WINDOWS_DIR_SEPARATOR = '\\'
|
5
|
+
|
6
|
+
attr_accessor :path_items
|
7
|
+
|
8
|
+
def initialize filename
|
9
|
+
filename = filename.gsub(WINDOWS_DIR_SEPARATOR, DIR_SEPARATOR)
|
10
|
+
@path_items = filename.split(DIR_SEPARATOR).delete_if{|item| item.empty?}
|
11
|
+
@absolute_path = filename.start_with? DIR_SEPARATOR
|
12
|
+
end
|
13
|
+
|
14
|
+
def absolute_path?
|
15
|
+
@absolute_path
|
16
|
+
end
|
17
|
+
|
18
|
+
def relative_path?
|
19
|
+
not absolute_path?
|
20
|
+
end
|
21
|
+
|
22
|
+
def without_extension
|
23
|
+
if @path_items.size > 0 and @path_items.last.include? '.' then
|
24
|
+
Filename.new(to_s.split('.')[0..-2].join('.'))
|
25
|
+
else
|
26
|
+
clone
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def extract_last_path_item
|
31
|
+
Filename.new(nil_to_empty_string @path_items.last)
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_last_path_item
|
35
|
+
Filename.new(make_string(@path_items[0..-2]))
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_unix_s
|
39
|
+
make_string @path_items
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_windows_s
|
43
|
+
make_string @path_items, WINDOWS_DIR_SEPARATOR
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
to_unix_s
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def make_string the_path_items, seperator=DIR_SEPARATOR
|
53
|
+
prefix = absolute_path? ? seperator : ''
|
54
|
+
prefix + the_path_items.join(seperator)
|
55
|
+
end
|
56
|
+
|
57
|
+
def nil_to_empty_string object
|
58
|
+
object.nil? ? "" : object
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'zip/zip'
|
2
|
+
require 'zip/zipfilesystem'
|
3
|
+
|
4
|
+
class SessionZipper
|
5
|
+
|
6
|
+
def compress(path)
|
7
|
+
path.sub!(%r[/$],'')
|
8
|
+
archive = File.join(path,File.basename(path))+'.zip'
|
9
|
+
FileUtils.rm archive, :force=>true
|
10
|
+
|
11
|
+
Zip::ZipFile.open(archive, 'w') do |zipfile|
|
12
|
+
Dir["#{path}/**/**"].reject{|f|f==archive}.each do |file|
|
13
|
+
zipfile.add(file.sub(path+'/',''),file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
archive
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'shell_process'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
class ShellWrapper
|
6
|
+
|
7
|
+
MAX_STDOUT_LENGTH = 100000
|
8
|
+
|
9
|
+
def cp source, destination
|
10
|
+
FileUtils.cp source, destination
|
11
|
+
end
|
12
|
+
|
13
|
+
def cp_r source, destination
|
14
|
+
FileUtils.cp_r source, destination
|
15
|
+
end
|
16
|
+
|
17
|
+
def rm_r file_regex
|
18
|
+
files_in_dir_tree('.', file_regex).each do |file|
|
19
|
+
FileUtils.rm file
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def mkdir dir
|
24
|
+
FileUtils.mkdir dir
|
25
|
+
end
|
26
|
+
|
27
|
+
def mkdir_p dirs
|
28
|
+
FileUtils.mkdir_p dirs
|
29
|
+
end
|
30
|
+
|
31
|
+
def rename old_filename, new_filename
|
32
|
+
File.rename old_filename, new_filename
|
33
|
+
end
|
34
|
+
|
35
|
+
def current_file
|
36
|
+
__FILE__
|
37
|
+
end
|
38
|
+
|
39
|
+
def execute command
|
40
|
+
process = ShellProcess.new
|
41
|
+
redirect_stderr_to_stdout = "2>&1"
|
42
|
+
spec_pipe = IO.popen("#{command} #{redirect_stderr_to_stdout}", "r")
|
43
|
+
process.output = spec_pipe.read MAX_STDOUT_LENGTH
|
44
|
+
spec_pipe.close
|
45
|
+
process.return_code = $?.exitstatus
|
46
|
+
puts process.output unless process.output.nil?
|
47
|
+
process
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_file filename, content
|
51
|
+
file = File.new filename, "w"
|
52
|
+
file << content
|
53
|
+
file.close
|
54
|
+
end
|
55
|
+
|
56
|
+
def read_file filename
|
57
|
+
file = File.new filename
|
58
|
+
content = file.read
|
59
|
+
file.close
|
60
|
+
content
|
61
|
+
end
|
62
|
+
|
63
|
+
def creation_time filename
|
64
|
+
File.ctime(filename)
|
65
|
+
end
|
66
|
+
|
67
|
+
def modification_time filename
|
68
|
+
File.mtime(filename)
|
69
|
+
end
|
70
|
+
|
71
|
+
def real_dir_entries dir
|
72
|
+
Dir.new(dir).entries - ["..", "."]
|
73
|
+
end
|
74
|
+
|
75
|
+
def files_in_dir dir, regexp_pattern=nil
|
76
|
+
Dir.new(dir).entries.find_all{|entry|
|
77
|
+
file_matches_regexp? entry, regexp_pattern
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def files_in_dir_tree dir, regexp_pattern=nil
|
82
|
+
Dir.glob("#{dir}/**/*").find_all{|entry|
|
83
|
+
file_matches_regexp? entry, regexp_pattern
|
84
|
+
}.sort
|
85
|
+
end
|
86
|
+
|
87
|
+
def file_matches_regexp? dir_entry, regexp_pattern
|
88
|
+
File.file?(dir_entry) and (not regexp_pattern or dir_entry =~ Regexp.new(regexp_pattern))
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def newest_dir_entry dir, files=nil
|
93
|
+
unless files then files = real_dir_entries(dir) end
|
94
|
+
files.sort_by do |entry|
|
95
|
+
complete_path = File.join dir, entry
|
96
|
+
File.mtime(complete_path)
|
97
|
+
end.last
|
98
|
+
end
|
99
|
+
|
100
|
+
def file? filename
|
101
|
+
File.file? filename
|
102
|
+
end
|
103
|
+
|
104
|
+
def open_with_default_app filename
|
105
|
+
execute "#{open_command_name} #{filename}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def read_properties filename
|
109
|
+
begin
|
110
|
+
YAML.load_file filename
|
111
|
+
rescue
|
112
|
+
raise PropertyFileMissingException.new filename
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def remove_command_name
|
117
|
+
windows? ? 'del' : 'rm'
|
118
|
+
end
|
119
|
+
|
120
|
+
def open_command_name
|
121
|
+
if windows? then
|
122
|
+
'start'
|
123
|
+
elsif mac? then
|
124
|
+
'open'
|
125
|
+
else
|
126
|
+
'xdg-open'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def expand_run_command command
|
131
|
+
if command.end_with?(".sh") then
|
132
|
+
"bash #{command}"
|
133
|
+
else
|
134
|
+
command
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def shell_extension
|
139
|
+
windows? ? 'cmd' : 'sh'
|
140
|
+
end
|
141
|
+
|
142
|
+
def path_separator
|
143
|
+
windows? ? ';' : ':'
|
144
|
+
end
|
145
|
+
|
146
|
+
def dir_separator
|
147
|
+
File::ALT_SEPARATOR ? File::ALT_SEPARATOR : File::SEPARATOR
|
148
|
+
end
|
149
|
+
|
150
|
+
def windows?
|
151
|
+
platform = RUBY_PLATFORM.downcase
|
152
|
+
platform.include?("windows") or platform.include?("mingw32")
|
153
|
+
end
|
154
|
+
|
155
|
+
def mac?
|
156
|
+
platform = RUBY_PLATFORM.downcase
|
157
|
+
platform.include?("universal-darwin")
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'filename'
|
2
|
+
|
3
|
+
describe Filename do
|
4
|
+
|
5
|
+
it "should detect if the path is absolute or relative" do
|
6
|
+
Filename.new('').absolute_path?.should be_false
|
7
|
+
Filename.new('/').absolute_path?.should be_true
|
8
|
+
Filename.new('').relative_path?.should be_true
|
9
|
+
Filename.new('/').relative_path?.should be_false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should split into path items" do
|
13
|
+
Filename.new('').path_items.should == []
|
14
|
+
Filename.new('a').path_items.should == ['a']
|
15
|
+
Filename.new('/a').path_items.should == ['a']
|
16
|
+
Filename.new('/a/').path_items.should == ['a']
|
17
|
+
Filename.new('a/b').path_items.should == ['a', 'b']
|
18
|
+
Filename.new('/a/b').path_items.should == ['a', 'b']
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should remove the extension" do
|
22
|
+
Filename.new('').without_extension.to_s.should == ''
|
23
|
+
Filename.new('a').without_extension.to_s.should == 'a'
|
24
|
+
Filename.new('a.b').without_extension.to_s.should == 'a'
|
25
|
+
Filename.new('a.b.c').without_extension.to_s.should == 'a.b'
|
26
|
+
Filename.new('a.b/c').without_extension.to_s.should == 'a.b/c'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should remove the last element of a dir path' do
|
30
|
+
Filename.new('').remove_last_path_item.to_s.should == ""
|
31
|
+
Filename.new('/').remove_last_path_item.to_s.should == "/"
|
32
|
+
Filename.new('a').remove_last_path_item.to_s.should == ""
|
33
|
+
Filename.new('a/').remove_last_path_item.to_s.should == ""
|
34
|
+
Filename.new('/a').remove_last_path_item.to_s.should == "/"
|
35
|
+
Filename.new('/a/').remove_last_path_item.to_s.should == "/"
|
36
|
+
Filename.new('a/b').remove_last_path_item.to_s.should == "a"
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should extract the last element of a dir path' do
|
40
|
+
Filename.new('').extract_last_path_item.to_s.should == ""
|
41
|
+
Filename.new('/').extract_last_path_item.to_s.should == ""
|
42
|
+
Filename.new('a').extract_last_path_item.to_s.should == "a"
|
43
|
+
Filename.new('a/b/').extract_last_path_item.to_s.should == "b"
|
44
|
+
Filename.new('a/b/c').extract_last_path_item.to_s.should == "c"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return a Unix like string representation" do
|
48
|
+
Filename.new('a/b').to_unix_s.should == 'a/b'
|
49
|
+
Filename.new('/a/b').to_unix_s.should == '/a/b'
|
50
|
+
Filename.new('a\\b').to_unix_s.should == 'a/b'
|
51
|
+
Filename.new('\\a\\b').to_unix_s.should == '/a/b'
|
52
|
+
Filename.new('a/').to_unix_s.should == 'a'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return a Windows like string representation" do
|
56
|
+
Filename.new('a/b').to_windows_s.should == 'a\\b'
|
57
|
+
Filename.new('/a/b').to_windows_s.should == '\\a\\b'
|
58
|
+
Filename.new('a\\b').to_windows_s.should == 'a\\b'
|
59
|
+
Filename.new('\\a\\b').to_windows_s.should == '\\a\\b'
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return a Unix like string representation by default" do
|
63
|
+
Filename.new('/a/b').to_s.should == '/a/b'
|
64
|
+
Filename.new('a\\b').to_s.should == 'a/b'
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'shell_wrapper'
|
2
|
+
|
3
|
+
describe ShellWrapper do
|
4
|
+
|
5
|
+
before (:each) do
|
6
|
+
@shell = ShellWrapper.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should return the files in a directory" do
|
10
|
+
Dir.should_receive(:new).with('myDir').and_return ['file1', 'dir', 'file2']
|
11
|
+
File.should_receive(:file?).with('file1').and_return true
|
12
|
+
File.should_receive(:file?).with('dir').and_return false
|
13
|
+
File.should_receive(:file?).with('file2').and_return true
|
14
|
+
@shell.files_in_dir('myDir').should == ['file1', 'file2']
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should filter files by regex pattern" do
|
18
|
+
Dir.should_receive(:new).with('myDir').and_return ['file1.rb', 'file2.py']
|
19
|
+
File.should_receive(:file?).any_number_of_times.and_return true
|
20
|
+
@shell.files_in_dir('myDir', '.*\.rb').should == ['file1.rb']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should filter files by regex pattern recursivly and sort result alphabetically" do
|
24
|
+
Dir.should_receive(:glob).with('myDir/**/*').and_return ['file3.rb', 'file2.rb', 'file1.py']
|
25
|
+
File.should_receive(:file?).any_number_of_times.and_return true
|
26
|
+
@shell.files_in_dir_tree('myDir', '.*\.rb').should == ['file2.rb', "file3.rb"]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should omit . and .. from dir list" do
|
30
|
+
Dir.should_receive(:new).and_return ['.', '..', 'bar', 'bar2']
|
31
|
+
@shell.real_dir_entries('foo').should == ['bar', 'bar2']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should omit . and .. when retrieving the newest file in a directory" do
|
35
|
+
Dir.should_receive(:new).and_return ['.', '..', 'bar', 'bar2']
|
36
|
+
File.should_receive(:mtime).with('foo/bar').and_return 2
|
37
|
+
File.should_receive(:mtime).with('foo/bar2').and_return 1
|
38
|
+
@shell.newest_dir_entry('foo').should == "bar"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should retrieve the newest dir from a file list" do
|
42
|
+
File.should_receive(:mtime).with('foo/bar/file1').and_return 2
|
43
|
+
File.should_receive(:mtime).with('foo/file2').and_return 1
|
44
|
+
@shell.newest_dir_entry('foo', ['bar/file1', 'file2']).should == 'bar/file1'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should prepend *.sh start scripts with 'bash'" do
|
48
|
+
@shell.expand_run_command('aCommand.sh').should == 'bash aCommand.sh'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should not prepend *.bat start scripts with anything" do
|
52
|
+
@shell.expand_run_command('aCommand.bat').should == 'aCommand.bat'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not prepend *.cmd start scripts with anything" do
|
56
|
+
@shell.expand_run_command('aCommand.cmd').should == 'aCommand.cmd'
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shell_utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- CodersDojo-Team
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-09-14 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rubyzip
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 9
|
30
|
+
- 4
|
31
|
+
version: 0.9.4
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Shell utilities.
|
35
|
+
email: codersdojo@it-agile.de
|
36
|
+
executables: []
|
37
|
+
|
38
|
+
extensions: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
files:
|
43
|
+
- lib/filename.rb
|
44
|
+
- lib/session_zipper.rb
|
45
|
+
- lib/shell_argument_exception.rb
|
46
|
+
- lib/shell_process.rb
|
47
|
+
- lib/shell_wrapper.rb
|
48
|
+
has_rdoc: true
|
49
|
+
homepage:
|
50
|
+
licenses: []
|
51
|
+
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
segments:
|
62
|
+
- 1
|
63
|
+
- 8
|
64
|
+
- 6
|
65
|
+
version: 1.8.6
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: shell_utils
|
76
|
+
rubygems_version: 1.3.6
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Shell Utilities
|
80
|
+
test_files:
|
81
|
+
- spec/filename_spec.rb
|
82
|
+
- spec/shell_wrapper_spec.rb
|