shlauncher 0.1.3
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/ChangeLog +11 -0
- data/README.rdoc +64 -0
- data/Rakefile +147 -0
- data/bin/shlauncher_test +20 -0
- data/bin/tractor +5 -0
- data/lib/tractor.rb +88 -0
- data/templates/ChangeLog +4 -0
- data/templates/README +30 -0
- data/templates/Rakefile +77 -0
- data/templates/bin/shlauncher +5 -0
- data/templates/lib/shlauncher.rb +247 -0
- data/test/script/README +0 -0
- data/test/script/example +12 -0
- data/test/script/example.bak +12 -0
- data/test/script/example~ +12 -0
- data/test/script/foo/bar +5 -0
- data/test/script/foo/bar~ +5 -0
- data/test/script/foo/baz +5 -0
- data/test/script/nocomment +3 -0
- data/test/shlauncher_test.rb +59 -0
- data/test/tractor_test.rb +14 -0
- metadata +97 -0
data/ChangeLog
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
= Shlauncher - A shell script launcher
|
3
|
+
|
4
|
+
Scaffold your custom launcher. Launch from your shell script ( and also Ruby script ) collection.
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
=== Archive Installation
|
9
|
+
|
10
|
+
rake install
|
11
|
+
|
12
|
+
=== Gem Installation
|
13
|
+
|
14
|
+
gem install wtnabe-shlauncher
|
15
|
+
|
16
|
+
== Features/Problems
|
17
|
+
|
18
|
+
* scaffold launcher ( by `tractor' command )
|
19
|
+
* collect scripts in script/ directory and list up as task
|
20
|
+
* exec all tasks in some scope
|
21
|
+
* generate gem
|
22
|
+
|
23
|
+
* On Windows, only Ruby scripts can be executed.
|
24
|
+
|
25
|
+
== Synopsis
|
26
|
+
|
27
|
+
Scaffold your launcher.
|
28
|
+
|
29
|
+
$ tractor LAUNCHER_NAME
|
30
|
+
|
31
|
+
Put your script into script/ directory and make executable.
|
32
|
+
|
33
|
+
$ cd LAUNCHER_NAME
|
34
|
+
$ ./bin/LAUNCHER_NAME
|
35
|
+
$ echo '# script sample' > script/sample
|
36
|
+
$ chmod a+x script/sample
|
37
|
+
|
38
|
+
Run your launcher.
|
39
|
+
|
40
|
+
$ ./bin/LAUNCHER_NAME
|
41
|
+
|
42
|
+
LAUNCHER_NAME sample # script sample
|
43
|
+
|
44
|
+
Generate gem from your launcher.
|
45
|
+
|
46
|
+
$ rake gem
|
47
|
+
$ ls pkg
|
48
|
+
|
49
|
+
LAUNCHER_NAME-0.0.1.gem
|
50
|
+
|
51
|
+
== Thanks
|
52
|
+
|
53
|
+
`Cutagem' inspires and be helpful to this product.
|
54
|
+
|
55
|
+
* http://github.com/genki/cutagem/tree/master
|
56
|
+
* http://cutagem.rubyforge.org/
|
57
|
+
|
58
|
+
Thank you, cho45 and genki !
|
59
|
+
|
60
|
+
== Copyright
|
61
|
+
|
62
|
+
Author:: wtnabe <wtnabe@gmail.com>
|
63
|
+
Copyright:: Copyright (c) 2009 wtnabe
|
64
|
+
License:: Two-claused BSD
|
data/Rakefile
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rake/packagetask'
|
8
|
+
require 'rake/gempackagetask'
|
9
|
+
require 'rake/rdoctask'
|
10
|
+
require 'rake/contrib/rubyforgepublisher'
|
11
|
+
require 'rake/contrib/sshpublisher'
|
12
|
+
require 'fileutils'
|
13
|
+
require 'lib/tractor'
|
14
|
+
require 'templates/lib/shlauncher'
|
15
|
+
include FileUtils
|
16
|
+
|
17
|
+
NAME = "shlauncher"
|
18
|
+
AUTHOR = "wtnabe"
|
19
|
+
EMAIL = "wtnabe@gmail.com"
|
20
|
+
DESCRIPTION = "A shell script launcher"
|
21
|
+
RUBYFORGE_PROJECT = ""
|
22
|
+
HOMEPATH = ""
|
23
|
+
BIN_FILES = %w( tractor )
|
24
|
+
|
25
|
+
VERS = Shlauncher_Tractor::VERSION
|
26
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
27
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
28
|
+
RDOC_OPTS = [
|
29
|
+
'--title', "#{NAME} documentation",
|
30
|
+
"--charset", "utf-8",
|
31
|
+
"--opname", "index.html",
|
32
|
+
"--line-numbers",
|
33
|
+
"--main", "README.rdoc",
|
34
|
+
"--inline-source",
|
35
|
+
]
|
36
|
+
|
37
|
+
task :default => [:test]
|
38
|
+
task :package => [:clean]
|
39
|
+
|
40
|
+
Rake::TestTask.new("test") do |t|
|
41
|
+
t.libs << "test"
|
42
|
+
t.pattern = "test/**/*_test.rb"
|
43
|
+
t.verbose = true
|
44
|
+
end
|
45
|
+
|
46
|
+
spec = Gem::Specification.new do |s|
|
47
|
+
s.name = NAME
|
48
|
+
s.version = VERS
|
49
|
+
s.platform = Gem::Platform::RUBY
|
50
|
+
s.has_rdoc = true
|
51
|
+
s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
|
52
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
53
|
+
s.summary = "Scaffold your custom launcher. Launch from your shell script ( and also Ruby script ) collection."
|
54
|
+
s.description = DESCRIPTION
|
55
|
+
s.author = AUTHOR
|
56
|
+
s.email = EMAIL
|
57
|
+
s.homepage = HOMEPATH
|
58
|
+
s.executables = BIN_FILES
|
59
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
60
|
+
s.bindir = "bin"
|
61
|
+
s.require_path = "lib"
|
62
|
+
#s.autorequire = ""
|
63
|
+
s.test_files = Dir["test/*_test.rb"]
|
64
|
+
|
65
|
+
s.add_dependency('rake', '>= 0')
|
66
|
+
#s.required_ruby_version = '>= 1.8.2'
|
67
|
+
|
68
|
+
s.files = %w(README.rdoc ChangeLog Rakefile) +
|
69
|
+
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
70
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
71
|
+
Dir.glob("examples/**/*.rb") +
|
72
|
+
Dir.glob("tools/*.rb") +
|
73
|
+
Dir.glob("rails/*.rb")
|
74
|
+
|
75
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
76
|
+
end
|
77
|
+
|
78
|
+
Rake::GemPackageTask.new(spec) do |p|
|
79
|
+
p.need_tar = true
|
80
|
+
p.gem_spec = spec
|
81
|
+
end
|
82
|
+
|
83
|
+
task :install do
|
84
|
+
name = "#{NAME}-#{VERS}.gem"
|
85
|
+
sh %{rake package}
|
86
|
+
sh %{sudo gem install pkg/#{name}}
|
87
|
+
end
|
88
|
+
|
89
|
+
task :uninstall => [:clean] do
|
90
|
+
sh %{sudo gem uninstall #{NAME}}
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
Rake::RDocTask.new do |rdoc|
|
95
|
+
rdoc.rdoc_dir = 'html'
|
96
|
+
rdoc.options += RDOC_OPTS
|
97
|
+
rdoc.template = "resh"
|
98
|
+
#rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
99
|
+
if ENV['DOC_FILES']
|
100
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
101
|
+
else
|
102
|
+
rdoc.rdoc_files.include('README.rdoc', 'ChangeLog')
|
103
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
104
|
+
rdoc.rdoc_files.include('ext/**/*.c')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
desc "Publish to RubyForge"
|
109
|
+
task :rubyforge => [:rdoc, :package] do
|
110
|
+
require 'rubyforge'
|
111
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'watanabe').upload
|
112
|
+
end
|
113
|
+
|
114
|
+
desc 'Package and upload the release to rubyforge.'
|
115
|
+
task :release => [:clean, :package] do |t|
|
116
|
+
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
117
|
+
abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
|
118
|
+
pkg = "pkg/#{NAME}-#{VERS}"
|
119
|
+
|
120
|
+
require 'rubyforge'
|
121
|
+
rf = RubyForge.new.configure
|
122
|
+
puts "Logging in"
|
123
|
+
rf.login
|
124
|
+
|
125
|
+
c = rf.userconfig
|
126
|
+
# c["release_notes"] = description if description
|
127
|
+
# c["release_changes"] = changes if changes
|
128
|
+
c["preformatted"] = true
|
129
|
+
|
130
|
+
files = [
|
131
|
+
"#{pkg}.tgz",
|
132
|
+
"#{pkg}.gem"
|
133
|
+
].compact
|
134
|
+
|
135
|
+
puts "Releasing #{NAME} v. #{VERS}"
|
136
|
+
rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
|
137
|
+
end
|
138
|
+
|
139
|
+
desc 'Show information about the gem.'
|
140
|
+
task :debug_gem do
|
141
|
+
puts spec.to_ruby
|
142
|
+
end
|
143
|
+
|
144
|
+
desc 'Update gem spec'
|
145
|
+
task :gemspec do
|
146
|
+
open("#{NAME}.gemspec", 'w').write spec.to_ruby
|
147
|
+
end
|
data/bin/shlauncher_test
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#! /usr/bin/env rake -f
|
2
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
3
|
+
|
4
|
+
require File.dirname( __FILE__ ) + '/../templates/lib/shlauncher'
|
5
|
+
|
6
|
+
launcher = Shlauncher.new( File.dirname( __FILE__ ) + '/../test/script' )
|
7
|
+
|
8
|
+
launcher.tasks.each { |t|
|
9
|
+
desc launcher.desc( t )
|
10
|
+
task t do
|
11
|
+
launcher.launch( t )
|
12
|
+
end
|
13
|
+
}
|
14
|
+
|
15
|
+
task :default do
|
16
|
+
app = Rake.application
|
17
|
+
app.name = File.basename( __FILE__ )
|
18
|
+
app.options.show_task_pattern = Regexp.new('')
|
19
|
+
app.display_tasks_and_comments
|
20
|
+
end
|
data/bin/tractor
ADDED
data/lib/tractor.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
class Shlauncher_Tractor
|
8
|
+
VERSION = "0.1.3"
|
9
|
+
|
10
|
+
include FileUtils::Verbose
|
11
|
+
class RakeNotFound < StandardError; end
|
12
|
+
|
13
|
+
def initialize( argv )
|
14
|
+
@argv = argv
|
15
|
+
@launcher = nil
|
16
|
+
@email = nil
|
17
|
+
@author = nil
|
18
|
+
@description = nil
|
19
|
+
end
|
20
|
+
attr_reader :launcher, :email, :author, :description
|
21
|
+
|
22
|
+
def run
|
23
|
+
@launcher = parse_args
|
24
|
+
if ( File.exist?( launcher_dir ) )
|
25
|
+
puts "'#{launcher}' directory already existed."
|
26
|
+
else
|
27
|
+
deploy_template
|
28
|
+
rewrite_template
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def launcher_dir
|
33
|
+
return File.join( Dir.pwd, launcher )
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy_template
|
37
|
+
cp_r( File.expand_path( File.dirname( __FILE__ ) + '/../templates/' ),
|
38
|
+
launcher_dir )
|
39
|
+
Dir.chdir( launcher_dir ) {
|
40
|
+
mkdir( 'script' )
|
41
|
+
mv( 'bin/shlauncher', "bin/#{launcher}" )
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def rewrite_template
|
46
|
+
Dir.chdir( launcher_dir ) {
|
47
|
+
targets = %w( Rakefile ChangeLog README )
|
48
|
+
targets.each { |file|
|
49
|
+
open( file, 'r+' ) { |f|
|
50
|
+
erb = ERB.new( f.read )
|
51
|
+
f.rewind
|
52
|
+
f.truncate( 0 )
|
53
|
+
f.puts erb.result( binding )
|
54
|
+
}
|
55
|
+
puts "rewrited #{file}"
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_args
|
61
|
+
app = File.basename( $0 )
|
62
|
+
opt = OptionParser.new { |parser|
|
63
|
+
parser.version = VERSION
|
64
|
+
parser.banner =<<EOD
|
65
|
+
#{app} #{VERSION}
|
66
|
+
|
67
|
+
Usage: #{app} LAUNCHER_NAME
|
68
|
+
EOD
|
69
|
+
parser.on( '-e', '--email ADDR' ) { |email|
|
70
|
+
@email = email
|
71
|
+
}
|
72
|
+
parser.on( '-a', '--author NAME' ) { |author|
|
73
|
+
@author = author
|
74
|
+
}
|
75
|
+
parser.on( '-d', '--description DESC' ) { |desc|
|
76
|
+
@description = desc
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
rest_args = opt.parse!( @argv )
|
81
|
+
if ( rest_args.size > 0 )
|
82
|
+
return rest_args.first
|
83
|
+
else
|
84
|
+
puts opt.help
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/templates/ChangeLog
ADDED
data/templates/README
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
= <%=launcher%>
|
3
|
+
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
<%=description%>
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
=== Archive Installation
|
12
|
+
|
13
|
+
rake install
|
14
|
+
|
15
|
+
=== Gem Installation
|
16
|
+
|
17
|
+
gem install <%=launcher%>
|
18
|
+
|
19
|
+
|
20
|
+
== Features/Problems
|
21
|
+
|
22
|
+
|
23
|
+
== Synopsis
|
24
|
+
|
25
|
+
|
26
|
+
== Copyright
|
27
|
+
|
28
|
+
Author:: <%=author%> <<%=email%>>
|
29
|
+
Copyright:: Copyright (c) <%=Time.now.strftime("%Y")%> <%=author%>
|
30
|
+
License::
|
data/templates/Rakefile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/clean'
|
6
|
+
require 'rake/packagetask'
|
7
|
+
require 'rake/gempackagetask'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'lib/shlauncher'
|
10
|
+
include FileUtils
|
11
|
+
|
12
|
+
NAME = "<%=launcher%>"
|
13
|
+
AUTHOR = "<%=author%>"
|
14
|
+
EMAIL = "<%=email%>"
|
15
|
+
DESCRIPTION = "<%=description%>"
|
16
|
+
BIN_FILES = %w( <%=launcher%> )
|
17
|
+
|
18
|
+
VERS = Shlauncher::VERSION
|
19
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
20
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
21
|
+
|
22
|
+
task :default do
|
23
|
+
app = Rake.application
|
24
|
+
app.options.show_task_pattern = Regexp.new('')
|
25
|
+
app.display_tasks_and_comments
|
26
|
+
end
|
27
|
+
|
28
|
+
task :package => [:clean]
|
29
|
+
|
30
|
+
spec = Gem::Specification.new do |s|
|
31
|
+
s.name = NAME
|
32
|
+
s.version = VERS
|
33
|
+
s.platform = Gem::Platform::RUBY
|
34
|
+
s.has_rdoc = false
|
35
|
+
s.summary = DESCRIPTION
|
36
|
+
s.description = DESCRIPTION
|
37
|
+
s.author = AUTHOR
|
38
|
+
s.email = EMAIL
|
39
|
+
s.executables = BIN_FILES
|
40
|
+
s.bindir = "bin"
|
41
|
+
s.require_path = "lib"
|
42
|
+
s.homepage = ""
|
43
|
+
s.rubyforge_project = ""
|
44
|
+
#s.autorequire = ""
|
45
|
+
|
46
|
+
s.add_dependency('rake', '>= 0')
|
47
|
+
#s.required_ruby_version = '>= 1.8.2'
|
48
|
+
|
49
|
+
s.files = %w(README ChangeLog Rakefile) +
|
50
|
+
Dir.glob("{bin,doc,etc,lib,script}/**/*")
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
Rake::GemPackageTask.new(spec) do |p|
|
55
|
+
p.need_tar = true
|
56
|
+
p.gem_spec = spec
|
57
|
+
end
|
58
|
+
|
59
|
+
task :install do
|
60
|
+
name = "#{NAME}-#{VERS}.gem"
|
61
|
+
sh %{rake package}
|
62
|
+
sh %{sudo gem install pkg/#{name}}
|
63
|
+
end
|
64
|
+
|
65
|
+
task :uninstall => [:clean] do
|
66
|
+
sh %{sudo gem uninstall #{NAME}}
|
67
|
+
end
|
68
|
+
|
69
|
+
desc 'Show information about the gem.'
|
70
|
+
task :debug_gem do
|
71
|
+
puts spec.to_ruby
|
72
|
+
end
|
73
|
+
|
74
|
+
desc 'Update gem spec'
|
75
|
+
task :gemspec do
|
76
|
+
open("#{NAME}.gemspec", 'w').write spec.to_ruby
|
77
|
+
end
|
@@ -0,0 +1,247 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
class Shlauncher
|
4
|
+
VERSION = '0.0.1'
|
5
|
+
|
6
|
+
LINEBREAK = /(?:\r\n|[\r\n])/
|
7
|
+
IGNORE_PATTERNS = %w( *~ *.bak CVS .svn )
|
8
|
+
|
9
|
+
class SubcomandNotExist < StandardError; end
|
10
|
+
|
11
|
+
def initialize( script_path = nil )
|
12
|
+
if ( script_path and File.directory?( script_path ) )
|
13
|
+
@script_path = File.expand_path( script_path )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def run
|
18
|
+
if ( ARGV.size == 0 )
|
19
|
+
show_info
|
20
|
+
else
|
21
|
+
argv = ARGV.dup
|
22
|
+
task = argv.shift
|
23
|
+
case task
|
24
|
+
when '-c', '--cat'
|
25
|
+
subcmd = argv.shift
|
26
|
+
if ( tasks.include?( subcmd ) )
|
27
|
+
show_script( subcmd )
|
28
|
+
else
|
29
|
+
subcommand_not_exist( subcmd )
|
30
|
+
end
|
31
|
+
when '-h', '--help'
|
32
|
+
puts usage
|
33
|
+
when '-V', '--version'
|
34
|
+
puts version
|
35
|
+
else
|
36
|
+
if ( tasks.include?( task ) )
|
37
|
+
launch_task( task, argv )
|
38
|
+
else
|
39
|
+
subcommand_not_exist( task )
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def subcommand_not_exist( task )
|
46
|
+
raise( SubcomandNotExist,
|
47
|
+
"A subcommand `#{task}' does not defined !" )
|
48
|
+
end
|
49
|
+
|
50
|
+
def version
|
51
|
+
return "#{File.basename( $0 )} ver. #{VERSION}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def usage
|
55
|
+
version + "\n\n" + <<EOD
|
56
|
+
Usage: #{File.basename( $0 )} [options] [subcommand [args]]
|
57
|
+
|
58
|
+
Options:
|
59
|
+
-c --cat cat script file
|
60
|
+
-h --help show this message
|
61
|
+
-V --version show version number
|
62
|
+
EOD
|
63
|
+
end
|
64
|
+
|
65
|
+
def show_info
|
66
|
+
if ( tasks.size == 0 )
|
67
|
+
puts usage
|
68
|
+
puts "\nNo commands defined."
|
69
|
+
else
|
70
|
+
show_tasks
|
71
|
+
end
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
|
75
|
+
def show_script( task )
|
76
|
+
puts File.open( File.join( script_path, command_path( task ) ) ).read
|
77
|
+
end
|
78
|
+
|
79
|
+
def show_tasks
|
80
|
+
puts "Defined tasks:"
|
81
|
+
maxlen_taskname = 0
|
82
|
+
tasks.map { |name|
|
83
|
+
if ( name.size > maxlen_taskname )
|
84
|
+
maxlen_taskname = name.size
|
85
|
+
end
|
86
|
+
name
|
87
|
+
}.map { |name|
|
88
|
+
puts truncate( "#{name.ljust( maxlen_taskname )} # #{desc( name )}",
|
89
|
+
terminal_width )
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def launch_task( task, args = nil )
|
94
|
+
command = File.join( script_path, command_path( task ) )
|
95
|
+
if ( File.directory?( command ) )
|
96
|
+
tasks( command_path( task ) ).each { |t|
|
97
|
+
launch_task( t, args )
|
98
|
+
}
|
99
|
+
else
|
100
|
+
command += " #{args.join(' ')}" if args
|
101
|
+
if ( unix? )
|
102
|
+
system( command )
|
103
|
+
else
|
104
|
+
system( 'ruby', command )
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def commands_ignored( path = nil )
|
110
|
+
base = ( path ) ? File.join( script_path, path ) : script_path
|
111
|
+
|
112
|
+
cmds = []
|
113
|
+
IGNORE_PATTERNS.each { |p|
|
114
|
+
Dir.chdir( base ) {
|
115
|
+
a = Dir.glob( p )
|
116
|
+
cmds += a if a.is_a?( Array )
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
return cmds.uniq
|
121
|
+
end
|
122
|
+
|
123
|
+
def tasks( path = nil )
|
124
|
+
base = ( path ) ? File.join( script_path, path ) : script_path
|
125
|
+
|
126
|
+
tasks = nil
|
127
|
+
Dir.chdir( base ) {
|
128
|
+
tasks = Dir.glob( '*' ).map { |f|
|
129
|
+
if ( File.directory?( f ) )
|
130
|
+
[f, tasks( (( path ) ? File.join( path, f ) : f) )]
|
131
|
+
elsif ( File.executable?( f ) and
|
132
|
+
!commands_ignored( path ).include?( f ) )
|
133
|
+
taskname = ( path ) ? task( File.join( path, f ) ) : f
|
134
|
+
if ( desc( taskname ).size > 0 )
|
135
|
+
taskname
|
136
|
+
else
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
else
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
}.compact.flatten.sort
|
143
|
+
}
|
144
|
+
|
145
|
+
return tasks
|
146
|
+
end
|
147
|
+
|
148
|
+
#
|
149
|
+
# extract first comment block
|
150
|
+
#
|
151
|
+
# * read only #-style comment
|
152
|
+
# * ignore shebang and local vars defining lines
|
153
|
+
# * ignore all after body started ( even #-style comment )
|
154
|
+
#
|
155
|
+
def desc( task )
|
156
|
+
command = command_path( task )
|
157
|
+
file = File.join( script_path, command )
|
158
|
+
if ( File.exist?( file ) and File.readable?( file ) )
|
159
|
+
if ( File.directory?( file ) )
|
160
|
+
"exec all tasks in scope `#{task}'"
|
161
|
+
else
|
162
|
+
body_started = false
|
163
|
+
File.open( file ).read.split( LINEBREAK ).map { |line|
|
164
|
+
if ( shebang_or_localvar_line?( line ) or empty_line?( line ) or
|
165
|
+
body_started )
|
166
|
+
nil
|
167
|
+
else
|
168
|
+
if ( not_comment_line?( line ) )
|
169
|
+
body_started = true
|
170
|
+
nil
|
171
|
+
else
|
172
|
+
line.sub( /\A#\s*/, '' )
|
173
|
+
end
|
174
|
+
end
|
175
|
+
}.compact.map { |e|
|
176
|
+
( e.size > 0 ) ? e : nil
|
177
|
+
}.compact.join( ", " )
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def command_path( task )
|
183
|
+
return task.gsub( /:/, '/' )
|
184
|
+
end
|
185
|
+
|
186
|
+
def task( command_path )
|
187
|
+
return command_path.gsub( /\//, ':' )
|
188
|
+
end
|
189
|
+
|
190
|
+
def script_path
|
191
|
+
if ( !@script_path )
|
192
|
+
@script_path = File.expand_path( File.dirname( __FILE__ ) + '/../script' )
|
193
|
+
end
|
194
|
+
|
195
|
+
return @script_path
|
196
|
+
end
|
197
|
+
|
198
|
+
def shebang_or_localvar_line?( line )
|
199
|
+
return ( /\A#!/ =~ line or /\A#\s*(-\*-.+:.+-\*-|vim:)/ =~ line )
|
200
|
+
end
|
201
|
+
|
202
|
+
def empty_line?( line )
|
203
|
+
return ( /[^\s]/ !~ line )
|
204
|
+
end
|
205
|
+
|
206
|
+
def not_comment_line?( line )
|
207
|
+
return ( /\A\s*#/ !~ line )
|
208
|
+
end
|
209
|
+
|
210
|
+
# copied from rake
|
211
|
+
|
212
|
+
def terminal_width
|
213
|
+
if ENV['RAKE_COLUMNS']
|
214
|
+
result = ENV['RAKE_COLUMNS'].to_i
|
215
|
+
else
|
216
|
+
result = unix? ? dynamic_width : 80
|
217
|
+
end
|
218
|
+
(result < 10) ? 80 : result
|
219
|
+
rescue
|
220
|
+
80
|
221
|
+
end
|
222
|
+
|
223
|
+
# Calculate the dynamic width of the
|
224
|
+
def dynamic_width
|
225
|
+
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
|
226
|
+
end
|
227
|
+
|
228
|
+
def dynamic_width_stty
|
229
|
+
%x{stty size 2>/dev/null}.split[1].to_i
|
230
|
+
end
|
231
|
+
|
232
|
+
def dynamic_width_tput
|
233
|
+
%x{tput cols 2>/dev/null}.to_i
|
234
|
+
end
|
235
|
+
|
236
|
+
def unix?
|
237
|
+
RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
|
238
|
+
end
|
239
|
+
|
240
|
+
def truncate(string, width)
|
241
|
+
if string.length <= width
|
242
|
+
string
|
243
|
+
else
|
244
|
+
( string[0, width-3] || "" ) + "..."
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
data/test/script/README
ADDED
File without changes
|
data/test/script/example
ADDED
data/test/script/foo/bar
ADDED
data/test/script/foo/baz
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require File.dirname(__FILE__) + '/../templates/lib/shlauncher'
|
5
|
+
|
6
|
+
class ShlauncherTest < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@obj = Shlauncher.new( File.dirname( __FILE__ ) + '/script' )
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_tasks
|
12
|
+
assert( @obj.tasks == %w( example foo foo:bar foo:baz ) )
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_commands_ignored
|
16
|
+
assert( @obj.commands_ignored == %w( example~ example.bak ) )
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_desc
|
20
|
+
assert( @obj.desc( 'example' ) == 'just example, Usage: example' )
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_command_path
|
24
|
+
assert( @obj.command_path( 'abc' ) == 'abc' )
|
25
|
+
assert( @obj.command_path( 'foo:bar' ) == 'foo/bar' )
|
26
|
+
assert( @obj.command_path( 'foo/bar' ) == 'foo/bar' )
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_task
|
30
|
+
assert( @obj.task( 'abc' ) == 'abc' )
|
31
|
+
assert( @obj.task( 'foo/bar' ) == 'foo:bar' )
|
32
|
+
assert( @obj.task( 'foo//bar' ) == 'foo::bar' )
|
33
|
+
assert( @obj.task( 'foo:bar' ) == 'foo:bar' )
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_script_path
|
37
|
+
assert( @obj.script_path == File.expand_path( File.dirname( __FILE__ ) ) + '/script' )
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_shebang_or_localvar_line?
|
41
|
+
assert( @obj.shebang_or_localvar_line?( '#! /bin/sh' ) )
|
42
|
+
assert( @obj.shebang_or_localvar_line?( '# -*- mode: ruby -*-' ) )
|
43
|
+
assert( @obj.shebang_or_localvar_line?( '# -*- coding: utf-8 -*-' ) )
|
44
|
+
assert( !@obj.shebang_or_localvar_line?( 'abc' ) )
|
45
|
+
assert( !@obj.shebang_or_localvar_line?( '# regular comment' ) )
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_empty_line?
|
49
|
+
assert( @obj.empty_line?( '' ) )
|
50
|
+
assert( @obj.empty_line?( ' ' ) )
|
51
|
+
assert( !@obj.empty_line?( '#' ) )
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_not_comment_line?
|
55
|
+
assert( @obj.not_comment_line?( 'abc' ) )
|
56
|
+
assert( !@obj.not_comment_line?( ' # ' ) )
|
57
|
+
assert( !@obj.not_comment_line?( '# ' ) )
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require File.dirname(__FILE__) + '/../lib/tractor'
|
5
|
+
|
6
|
+
class Shlauncher_TractorTest < Test::Unit::TestCase
|
7
|
+
def test_Shlauncher_Tractor
|
8
|
+
assert( true )
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@obj = Shlauncher_Tractor.new( ARGV )
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shlauncher
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- wtnabe
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-06 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: A shell script launcher
|
26
|
+
email: wtnabe@gmail.com
|
27
|
+
executables:
|
28
|
+
- tractor
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.rdoc
|
33
|
+
- ChangeLog
|
34
|
+
files:
|
35
|
+
- README.rdoc
|
36
|
+
- ChangeLog
|
37
|
+
- Rakefile
|
38
|
+
- bin/shlauncher_test
|
39
|
+
- bin/tractor
|
40
|
+
- test/script/example
|
41
|
+
- test/script/example.bak
|
42
|
+
- test/script/example~
|
43
|
+
- test/script/foo/bar
|
44
|
+
- test/script/foo/bar~
|
45
|
+
- test/script/foo/baz
|
46
|
+
- test/script/nocomment
|
47
|
+
- test/script/README
|
48
|
+
- test/shlauncher_test.rb
|
49
|
+
- test/tractor_test.rb
|
50
|
+
- lib/tractor.rb
|
51
|
+
- templates/bin/shlauncher
|
52
|
+
- templates/ChangeLog
|
53
|
+
- templates/lib/shlauncher.rb
|
54
|
+
- templates/Rakefile
|
55
|
+
- templates/README
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: ""
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --title
|
63
|
+
- shlauncher documentation
|
64
|
+
- --charset
|
65
|
+
- utf-8
|
66
|
+
- --opname
|
67
|
+
- index.html
|
68
|
+
- --line-numbers
|
69
|
+
- --main
|
70
|
+
- README.rdoc
|
71
|
+
- --inline-source
|
72
|
+
- --exclude
|
73
|
+
- ^(examples|extras)/
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project: ""
|
91
|
+
rubygems_version: 1.3.4
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Scaffold your custom launcher. Launch from your shell script ( and also Ruby script ) collection.
|
95
|
+
test_files:
|
96
|
+
- test/shlauncher_test.rb
|
97
|
+
- test/tractor_test.rb
|