knut_tools 0.1.0
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/lib/knut_tools.rb +45 -0
- data/lib/knut_tools/catch_output.rb +173 -0
- data/lib/knut_tools/file__END__.rb +88 -0
- data/lib/knut_tools/file_winlink.rb +52 -0
- data/lib/knut_tools/rake/gempackager.rb +551 -0
- data/lib/knut_tools/rake/testtask.rb +67 -0
- data/lib/knut_tools/required_what.rb +78 -0
- data/lib/knut_tools/yaml.rb +131 -0
- data/readme.html +63 -0
- data/readme.txt +47 -0
- data/unittest/test_file__END__.rb +77 -0
- data/unittest/test_file_winlink.rb +35 -0
- data/unittest/test_gempackager.rb +195 -0
- data/unittest/test_rake_testtask.rb +105 -0
- data/unittest/test_required_what.rb +72 -0
- data/unittest/test_yaml.rb +144 -0
- data/unittest/testdata/dummy_test.rb +3 -0
- data/unittest/testdata/hello_world.rb +8 -0
- metadata +112 -0
data/lib/knut_tools.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
==knut_tools/file__END__.rb
|
3
|
+
File-extensions for Ruby-scripts.
|
4
|
+
|
5
|
+
This extensions of the File-class allows to open Files, starting at __END__.
|
6
|
+
|
7
|
+
Details see file__END__.rb[link:files/lib/knut_tools/file__END___rb.html]
|
8
|
+
|
9
|
+
==knut_tools/catch_output.rb
|
10
|
+
Defines a function to catch outputs on stdout and stderr.
|
11
|
+
|
12
|
+
Details see catch_output.rb[link:files/lib/knut_tools/catch_output_rb.html]
|
13
|
+
|
14
|
+
==knut_tools/rot13.rb
|
15
|
+
extend String by pseudo-encryption.
|
16
|
+
|
17
|
+
Details see rot13.rb[link:files/lib/knut_tools/rot13_rb.html]
|
18
|
+
|
19
|
+
==knut_tools/required_what.rb
|
20
|
+
A little helper to detect file name conflicts between
|
21
|
+
different gems.
|
22
|
+
|
23
|
+
Details see required_what.rb[link:files/lib/knut_tools/required_what_rb.html]
|
24
|
+
|
25
|
+
|
26
|
+
==knut_tools/rake/testtask.rb
|
27
|
+
The knut_tools extends rake/testtask to run test in directories.
|
28
|
+
This may be necessary, if you have to test, if files are created correct
|
29
|
+
or test data can be find relative to your source.
|
30
|
+
|
31
|
+
Details see testtask.rb[link:files/lib/knut_tools/rake/testtask_rb.html]
|
32
|
+
|
33
|
+
==knut_tools/yaml.rb
|
34
|
+
Add yaml-related feature:
|
35
|
+
* sorted to_yaml for Hash with :SortKeys => true
|
36
|
+
* YAML.load_with_warning warns you about double Hash-keys.
|
37
|
+
|
38
|
+
Details see yaml.rb[link:files/lib/knut_tools/yaml_rb.html]
|
39
|
+
|
40
|
+
|
41
|
+
=end
|
42
|
+
|
43
|
+
module Knut_tools
|
44
|
+
VERSION = '0.1.0'
|
45
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
Catch screen output.
|
3
|
+
Can be used to avoid messages from programms called by system
|
4
|
+
|
5
|
+
Example:
|
6
|
+
require 'knut_tools/catch_output'
|
7
|
+
include Catch_output
|
8
|
+
stdout, stderr = catch_screen_output{
|
9
|
+
system('my_shell_application')
|
10
|
+
}
|
11
|
+
|
12
|
+
If you want to avoid the _include Catch_output_ you can
|
13
|
+
* use the dummy class Frame_catch_output
|
14
|
+
* make your own class
|
15
|
+
|
16
|
+
Example Frame_catch_output:
|
17
|
+
require 'knut_tools/catch_output'
|
18
|
+
stdout, stderr = Frame_catch_output.catch_screen_output{
|
19
|
+
system('my_shell_application')
|
20
|
+
}
|
21
|
+
|
22
|
+
Example own class:
|
23
|
+
require 'knut_tools/catch_output'
|
24
|
+
class MyCatch
|
25
|
+
include Catch_output
|
26
|
+
end
|
27
|
+
mycatch = MyCatch.new
|
28
|
+
|
29
|
+
stdout, stderr = mycatch.catch_screen_output{
|
30
|
+
system('my_shell_application')
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
Just to play a bit:
|
35
|
+
require 'knut_tools/catch_output'
|
36
|
+
|
37
|
+
puts 'Test 1'
|
38
|
+
a = Frame_catch_output.catch_stdout{
|
39
|
+
puts 'aa'
|
40
|
+
}
|
41
|
+
puts 'Test 1 durchgef�hrt, Ergebnis:'
|
42
|
+
puts a
|
43
|
+
puts '_'*50
|
44
|
+
|
45
|
+
puts 'Test 2'
|
46
|
+
a = Frame_catch_output.catch_stdout{
|
47
|
+
system('dir *')
|
48
|
+
}
|
49
|
+
|
50
|
+
puts 'Test 2 durchgef�hrt, Ergebnis:'
|
51
|
+
puts a
|
52
|
+
puts '_'*50
|
53
|
+
=end
|
54
|
+
|
55
|
+
#Class Tempfile for temporary redirection of stdout and stderr
|
56
|
+
require "tempfile"
|
57
|
+
|
58
|
+
=begin rdoc
|
59
|
+
Catch screen output.
|
60
|
+
Can be used to avoid messages from programms called by system
|
61
|
+
=end
|
62
|
+
module Catch_output
|
63
|
+
STDOUT_ORIG = STDOUT.clone()
|
64
|
+
STDERR_ORIG = STDERR.clone()
|
65
|
+
|
66
|
+
=begin rdoc
|
67
|
+
Catch stdout for the given block, but print stderr.
|
68
|
+
|
69
|
+
Example:
|
70
|
+
require 'knut_tools/catch_output'
|
71
|
+
include Catch_output
|
72
|
+
stdout = catch_stdout{
|
73
|
+
system('my_shell_application')
|
74
|
+
}
|
75
|
+
=end
|
76
|
+
def catch_stdout( &block )
|
77
|
+
#~ raise 'no block' unless block_given?
|
78
|
+
raise ArgumentError, 'no block' unless block.is_a?(Proc)
|
79
|
+
stdout, stderr = catch_screen_output( true, false, &block )
|
80
|
+
return stdout
|
81
|
+
end #catch_stdout()
|
82
|
+
|
83
|
+
=begin rdoc
|
84
|
+
Catch stderr for the given block, but print stdout.
|
85
|
+
|
86
|
+
Example:
|
87
|
+
require 'knut_tools/catch_output'
|
88
|
+
include Catch_output
|
89
|
+
stderr = catch_stderr{
|
90
|
+
system('my_shell_application')
|
91
|
+
}
|
92
|
+
|
93
|
+
=end
|
94
|
+
def catch_stderr( &block )
|
95
|
+
#~ raise 'no block' unless block_given?
|
96
|
+
raise ArgumentError, 'no block' unless block.is_a?(Proc)
|
97
|
+
stdout, stderr = catch_screen_output( false, true, &block )
|
98
|
+
return stderr
|
99
|
+
end #catch_stderr()
|
100
|
+
=begin rdoc
|
101
|
+
Catch the screen output (stdout and stderr) for the given block.
|
102
|
+
You can set, which output you want to catch.
|
103
|
+
|
104
|
+
Returnvalue is an array with the result of stdout and stderr.
|
105
|
+
If any output wasn't catched, the return value in the array is nil.
|
106
|
+
|
107
|
+
Example:
|
108
|
+
require 'knut_tools/catch_output'
|
109
|
+
include Catch_output
|
110
|
+
stdout, stderr = catch_screen_output{
|
111
|
+
system('my_shell_application')
|
112
|
+
}
|
113
|
+
=end
|
114
|
+
def catch_screen_output(
|
115
|
+
catch_stdout = true,
|
116
|
+
catch_stderr = true,
|
117
|
+
stdout_orig = STDOUT.clone(),
|
118
|
+
stderr_orig = STDERR.clone()
|
119
|
+
)
|
120
|
+
|
121
|
+
raise ArgumentError, 'no block' unless block_given?
|
122
|
+
|
123
|
+
if catch_stdout
|
124
|
+
#Create temporary file for stdout
|
125
|
+
tmpstdout = Tempfile.new( 'stdout')
|
126
|
+
#redirect stdout
|
127
|
+
STDOUT.reopen( tmpstdout )
|
128
|
+
end
|
129
|
+
if catch_stderr
|
130
|
+
#Create temporary file for stdout
|
131
|
+
tmpstderr = Tempfile.new( 'stderr')
|
132
|
+
#redirect stdout
|
133
|
+
STDERR.reopen( tmpstderr )
|
134
|
+
end
|
135
|
+
|
136
|
+
yield #Execute the block
|
137
|
+
|
138
|
+
if catch_stdout
|
139
|
+
#stdout is coming again to the screen.
|
140
|
+
tmpstdout.close()
|
141
|
+
STDOUT.reopen( stdout_orig)
|
142
|
+
|
143
|
+
# Get the result of stdout
|
144
|
+
tmpstdout.open()
|
145
|
+
stdout = tmpstdout.readlines().join
|
146
|
+
tmpstdout.close()
|
147
|
+
end
|
148
|
+
|
149
|
+
if catch_stderr
|
150
|
+
#stderr is coming again to the screen.
|
151
|
+
tmpstderr.close()
|
152
|
+
STDERR.reopen( stderr_orig)
|
153
|
+
|
154
|
+
# Get the result of stderr
|
155
|
+
tmpstderr.open()
|
156
|
+
stderr = tmpstderr.readlines().join
|
157
|
+
tmpstderr.close()
|
158
|
+
end
|
159
|
+
return [ stdout, stderr ]
|
160
|
+
end
|
161
|
+
end #Catch_output
|
162
|
+
|
163
|
+
=begin rdoc
|
164
|
+
Frame to use module Catch_output.
|
165
|
+
|
166
|
+
Example:
|
167
|
+
Frame_catch_output.catch_stdout{ puts 11 }
|
168
|
+
=end
|
169
|
+
class Frame_catch_output
|
170
|
+
class << self
|
171
|
+
include Catch_output
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
File-extensions for Ruby-scripts.
|
3
|
+
|
4
|
+
Inside Ruby-scripts text after __END__ is used like a "internal files".
|
5
|
+
|
6
|
+
Sometimes you want to use this data from other scripts.
|
7
|
+
|
8
|
+
This extensions of the File-class allows to open Files, starting at __END__.
|
9
|
+
|
10
|
+
Details see
|
11
|
+
* File.open_after_END
|
12
|
+
* File.readlines_after_END
|
13
|
+
* File.each_line_after_END
|
14
|
+
=end
|
15
|
+
|
16
|
+
class File
|
17
|
+
class << self
|
18
|
+
=begin rdoc
|
19
|
+
This methods behave like File#open, but it starts after __END__
|
20
|
+
|
21
|
+
Example:
|
22
|
+
filehandle = File.open_after_END('testdata/hello_world.rb')
|
23
|
+
filehandle.eachline{|line|
|
24
|
+
... #text after __END__
|
25
|
+
}
|
26
|
+
filehandle.close
|
27
|
+
|
28
|
+
or better:
|
29
|
+
File.open_after_END('testdata/hello_world.rb'){|filehandle|
|
30
|
+
filehandle.eachline{|line|
|
31
|
+
... #text after __END__
|
32
|
+
}
|
33
|
+
}
|
34
|
+
=end
|
35
|
+
def open_after_END( filename )
|
36
|
+
f = File.new(filename, 'r')
|
37
|
+
if filename =~ /\.rbw?\Z/
|
38
|
+
line = nil
|
39
|
+
while line !~ /^__END__\n/ and ! f.eof?
|
40
|
+
line = f.readline
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if block_given?
|
45
|
+
#~ f.each_line{|line| yield line }
|
46
|
+
yield f
|
47
|
+
else
|
48
|
+
return f
|
49
|
+
end #block_given?
|
50
|
+
end
|
51
|
+
=begin rdoc
|
52
|
+
Return content of script after __END__
|
53
|
+
|
54
|
+
Example:
|
55
|
+
File.readlines_after_END('testdata/hello_world.rb').each{|line|
|
56
|
+
#...
|
57
|
+
}
|
58
|
+
=end
|
59
|
+
def readlines_after_END( filename )
|
60
|
+
f = open_after_END( filename )
|
61
|
+
txt = f.readlines.join
|
62
|
+
f.close
|
63
|
+
return txt
|
64
|
+
end
|
65
|
+
=begin rdoc
|
66
|
+
Get all lines after __END__.
|
67
|
+
|
68
|
+
Example:
|
69
|
+
File.each_line_after_END('testdata/hello_world.rb'){|line|
|
70
|
+
#... lines after __END__
|
71
|
+
}
|
72
|
+
or
|
73
|
+
textarray = File.each_line_after_END('testdata/hello_world.rb')
|
74
|
+
=end
|
75
|
+
def each_line_after_END( filename )
|
76
|
+
f = open_after_END( filename )
|
77
|
+
res = true
|
78
|
+
if block_given?
|
79
|
+
res = f.each_line{|line| yield line }
|
80
|
+
else
|
81
|
+
res = f.readlines
|
82
|
+
end
|
83
|
+
f.close
|
84
|
+
return res
|
85
|
+
end
|
86
|
+
|
87
|
+
end #File
|
88
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
shortcut to define a link under windows.
|
3
|
+
=end
|
4
|
+
|
5
|
+
#~ fixme:
|
6
|
+
#~ genauer �berlegen
|
7
|
+
#~ interface mit hash (target bleibt, rest ist ableitbar)
|
8
|
+
#~ daten pr�fen.
|
9
|
+
|
10
|
+
require "win32/shortcut"
|
11
|
+
|
12
|
+
=begin rdoc
|
13
|
+
Usage:
|
14
|
+
mk_link( target, linkname )
|
15
|
+
mk_link( target, linkname, descr, workdir )
|
16
|
+
mk_link( 'readme.txt', 'readme.lnk', "Link to <#{target}>", "C:\\")
|
17
|
+
Builds a link, named linkname, to target.
|
18
|
+
Throws an error, if target does not exist.
|
19
|
+
=end
|
20
|
+
def mk_link( target, linkname,
|
21
|
+
descr="Link to <#{target}>",
|
22
|
+
workdir = "C:\\"
|
23
|
+
)
|
24
|
+
if File.exist?(target)
|
25
|
+
s = Win32::Shortcut.new(linkname)
|
26
|
+
s.description = descr
|
27
|
+
s.path = File.expand_path(target)
|
28
|
+
s.show_cmd = Win32::Shortcut::SHOWNORMAL
|
29
|
+
s.working_directory = workdir
|
30
|
+
s.save
|
31
|
+
#~ puts "Build link to #{target}"
|
32
|
+
else
|
33
|
+
raise Errno::ENOENT, "No link created to #{target}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
=begin
|
39
|
+
Quicktest.
|
40
|
+
See also unittest
|
41
|
+
=end
|
42
|
+
#~ mk_link( 'yaml.rb',
|
43
|
+
#~ "mylink.lnk",
|
44
|
+
#~ "This is a longer description of a link to yaml.rb"
|
45
|
+
#~ )
|
46
|
+
|
47
|
+
|
48
|
+
#~ mk_link( File.join( gemdir, 'gems', spec.full_name ),
|
49
|
+
#~ "dir_#{spec.full_name}.dir.lnk",
|
50
|
+
#~ "#{spec.name} version #{spec.version}"
|
51
|
+
#~ )
|
52
|
+
|
@@ -0,0 +1,551 @@
|
|
1
|
+
=begin rdoc
|
2
|
+
|
3
|
+
Usage:
|
4
|
+
require 'knut_tools/rake/gempackager.rb'
|
5
|
+
puts Gem_packer::Template
|
6
|
+
|
7
|
+
Take the result and start to add your data.
|
8
|
+
|
9
|
+
|
10
|
+
=Other packaging tools
|
11
|
+
There are different other packaging tools.
|
12
|
+
|
13
|
+
- hoe
|
14
|
+
- newgem
|
15
|
+
- bones
|
16
|
+
- gemhub
|
17
|
+
- echoe
|
18
|
+
- jeweler
|
19
|
+
|
20
|
+
(Source and discussion (German):
|
21
|
+
http://forum.ruby-portal.de/viewtopic.php?f=6&t=9517
|
22
|
+
)
|
23
|
+
|
24
|
+
==Short analyse of other tools
|
25
|
+
By some reasons the other tools doesn't fit my needs.
|
26
|
+
|
27
|
+
===hoe
|
28
|
+
* http://seattlerb.rubyforge.org/hoe/
|
29
|
+
* http://blog.emson.co.uk/2008/06/an-almost-fix-for-creating-rubygems-on-windows/
|
30
|
+
* http://nubyonrails.com/articles/tutorial-publishing-rubygems-with-hoe
|
31
|
+
|
32
|
+
Disadvantage:
|
33
|
+
* hoe becomes a dependecy in all gems.
|
34
|
+
* Problems with windows support
|
35
|
+
** http://blog.emson.co.uk/2008/06/an-almost-fix-for-creating-rubygems-on-windows/
|
36
|
+
** Seems to be solved, but you need some
|
37
|
+
|
38
|
+
|
39
|
+
===echoe
|
40
|
+
* http://blog.evanweaver.com/articles/2007/01/10/if-you-dont-want-to-hoe-echoe/
|
41
|
+
* http://gemcutter.org/gems/echoe
|
42
|
+
* http://blog.evanweaver.com/files/doc/fauna/echoe/files/README.html
|
43
|
+
|
44
|
+
Disadvantage:
|
45
|
+
* Manifest is build from scratch with tasks manifest and build
|
46
|
+
(Danger of overwritting your data)
|
47
|
+
* gemspec contains the test data files under "files"
|
48
|
+
|
49
|
+
|
50
|
+
=end
|
51
|
+
|
52
|
+
require 'rake'
|
53
|
+
require 'rubygems'
|
54
|
+
require "knut_tools/file_winlink.rb"
|
55
|
+
require 'knut_tools/rake/testtask.rb'
|
56
|
+
require 'rake/contrib/ftptools.rb'
|
57
|
+
|
58
|
+
=begin rdoc
|
59
|
+
Class to define an "extended" gemspec.
|
60
|
+
|
61
|
+
Defines all tasks to admin the gem (build, install, push to gemcutter...)
|
62
|
+
Details see #build_tasks.
|
63
|
+
=end
|
64
|
+
class Gem_packer
|
65
|
+
#Template for a new gem.
|
66
|
+
Template = <<-TEMPLATE
|
67
|
+
require 'knut_tools/rake/#{File.basename(__FILE__)}'
|
68
|
+
require 'knut_tools/rake/testtask.rb'
|
69
|
+
|
70
|
+
Gem_packer.new('my_gem', '0.1.0', {
|
71
|
+
:verbose => nil,
|
72
|
+
:versions => [],
|
73
|
+
:public => false,
|
74
|
+
}){|gemdef, spec|
|
75
|
+
#http://docs.rubygems.org/read/chapter/20
|
76
|
+
spec.author = "Knut Lickert"
|
77
|
+
spec.email = "knut@lickert.net"
|
78
|
+
spec.homepage = "http://www.rubypla.net/"
|
79
|
+
#~ spec.rubyforge_project = ''
|
80
|
+
spec.platform = Gem::Platform::RUBY
|
81
|
+
spec.summary = ""
|
82
|
+
spec.description = spec.summary
|
83
|
+
#~ spec.require_path = "lib"
|
84
|
+
spec.files = %w{
|
85
|
+
}
|
86
|
+
spec.test_files = %w{
|
87
|
+
}
|
88
|
+
#~ spec.test_files << Dir['unittest/expected/*']
|
89
|
+
spec.test_files.flatten!
|
90
|
+
|
91
|
+
spec.has_rdoc = true
|
92
|
+
#~ spec.rdoc_options << '--main' << 'lib/???'
|
93
|
+
|
94
|
+
#~ spec.add_dependency()
|
95
|
+
#~ spec.add_development_dependency('more_unit_test', '> 0.0.2') #assert_equal_filecontent
|
96
|
+
#~ spec.requirements << 'A (La)TeX-system'
|
97
|
+
|
98
|
+
#~ gemdef.versions << ??
|
99
|
+
#Define the tests (parameter: directory, test files)
|
100
|
+
#~ gemdef.define_test( 'unittest', FileList['test*.rb'])
|
101
|
+
|
102
|
+
#~ gemdef.public = true
|
103
|
+
#~ gemdef.add_ftp_connection(host, account, passwort, directory)
|
104
|
+
|
105
|
+
}
|
106
|
+
|
107
|
+
require 'creole/creole2doc' #needed for readme.html, readme.txt
|
108
|
+
#Build the html-readme from creole-source
|
109
|
+
rule '.html' => '.creole' do |t|
|
110
|
+
doc = Creole_document.new()
|
111
|
+
File.open(t.source){|f| doc << f }
|
112
|
+
doc.save(t.name)
|
113
|
+
end
|
114
|
+
#Build the text-readme from creole-source
|
115
|
+
rule '.txt' => '.creole' do |t|
|
116
|
+
doc = Creole_document.new()
|
117
|
+
File.open(t.source){|f| doc << f }
|
118
|
+
doc.save(t.name)
|
119
|
+
end
|
120
|
+
#~ task :default => 'readme.html'
|
121
|
+
#~ task :default => 'readme.txt'
|
122
|
+
|
123
|
+
desc "Copy the created gems to archive"
|
124
|
+
task :archive do
|
125
|
+
Dir["*-#{$version}.gem"].each{|gem_file|
|
126
|
+
FileUtils.copy(gem_file, "archive/File.basename(gem_file)")
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
#~ task :default => 'mygem:check'
|
131
|
+
task :default => :check
|
132
|
+
#~ task :default => :test
|
133
|
+
#~ task :default => :gem
|
134
|
+
#~ task :default => :install
|
135
|
+
#~ task :default => :ftp_rdoc
|
136
|
+
#~ task :default =>
|
137
|
+
#~ task :default =>
|
138
|
+
|
139
|
+
|
140
|
+
if $0 == __FILE__
|
141
|
+
app = Rake.application
|
142
|
+
app[:default].invoke
|
143
|
+
end
|
144
|
+
|
145
|
+
TEMPLATE
|
146
|
+
Template.gsub!(/^ /,'')
|
147
|
+
|
148
|
+
#Error thrown, if version conflict is detected.
|
149
|
+
class VersionError < RuntimeError; end
|
150
|
+
#Thrown, if a blocked task is called.
|
151
|
+
class BlockError < RuntimeError; end
|
152
|
+
#Struct with :host, :account, :password, :target_dir. Used in ftp_rdoc
|
153
|
+
FTP_DATA = Struct.new('FTP', :host, :account, :password, :target_dir)
|
154
|
+
|
155
|
+
=begin rdoc
|
156
|
+
Create a new gem definition.
|
157
|
+
|
158
|
+
Usage:
|
159
|
+
Gem_packer.new('test', '0.1.0', { ...options... }) do |gem_packer, spec|
|
160
|
+
spec.email = 'xx@testdomain.org'
|
161
|
+
# ...
|
162
|
+
end
|
163
|
+
Options may be:
|
164
|
+
* verbose
|
165
|
+
* public - allow push, ftp...
|
166
|
+
* versions - variables, which should be same as version.
|
167
|
+
|
168
|
+
Effects:
|
169
|
+
* Defines the tasks inside a namespace (see Gem_packer#build_tasks )
|
170
|
+
* Add the 'namespaced'-tasks to standard tasks.
|
171
|
+
=end
|
172
|
+
def initialize( name, version, options = {} )
|
173
|
+
@name = name
|
174
|
+
@version = version
|
175
|
+
@spec = Gem::Specification.new{ |spec|
|
176
|
+
spec.name = name
|
177
|
+
spec.version = version
|
178
|
+
}
|
179
|
+
|
180
|
+
@ftp_connections = []
|
181
|
+
|
182
|
+
raise ArgumentError unless options.is_a?(Hash)
|
183
|
+
#Copy all options to class settings.
|
184
|
+
@versions = options.delete(:versions)
|
185
|
+
@versions ||= []
|
186
|
+
@verbose = options.delete(:verbose)
|
187
|
+
@public = options.delete(:public)
|
188
|
+
#~ gemdef.add_ftp_connection(host, account, passwort, directory)
|
189
|
+
|
190
|
+
raise ArgumentError unless options.empty?
|
191
|
+
|
192
|
+
yield self, @spec if block_given?
|
193
|
+
|
194
|
+
puts "Build the tasks for #{@name}" if @verbose
|
195
|
+
build_tasks()
|
196
|
+
end
|
197
|
+
|
198
|
+
=begin rdoc
|
199
|
+
Tasks defined by this class. See #build_tasks().
|
200
|
+
|
201
|
+
Test tasks are defined with #define_test.
|
202
|
+
=end
|
203
|
+
TASKLIST = [ :default,
|
204
|
+
:check, :check_version, :check_gemspec,
|
205
|
+
:gem,
|
206
|
+
:install, :ftp_rdoc, :push,
|
207
|
+
:links,
|
208
|
+
]
|
209
|
+
=begin fixme
|
210
|
+
:check
|
211
|
+
:check_manifest: manifest lesen, vergliechen mit gemspec
|
212
|
+
|
213
|
+
* build_manifest (aus gemspec?
|
214
|
+
=end
|
215
|
+
|
216
|
+
#Spec-definition
|
217
|
+
attr_reader :spec
|
218
|
+
#Name of the gem
|
219
|
+
attr_reader :name
|
220
|
+
#Version of the gem
|
221
|
+
attr_reader :version
|
222
|
+
#Collection (Array) of version-elements. Have to be identic with version.
|
223
|
+
#Example: mygem_def.versions << Knut_tools::VERSION
|
224
|
+
attr_reader :versions
|
225
|
+
#Flag, if the gem is public (block "push" if false)
|
226
|
+
attr_accessor :public
|
227
|
+
|
228
|
+
=begin rdoc
|
229
|
+
Add a ftp-connection to copy the documentation.
|
230
|
+
|
231
|
+
The complete content of the rdoc-directory will be copied to the ftp-destination.
|
232
|
+
=end
|
233
|
+
def add_ftp_connection(host, account, passwort, directory)
|
234
|
+
puts "Add ftp-connection to #{host} for ftp_doc" if @verbose
|
235
|
+
@ftp_connections << FTP_DATA.new(host, account, passwort, directory)
|
236
|
+
end
|
237
|
+
|
238
|
+
=begin rdoc
|
239
|
+
Build all the tasks from TASKLIST inside a namespace.
|
240
|
+
|
241
|
+
Tasks outside the namespace get the "namespaced" tasks as prerequisite.
|
242
|
+
|
243
|
+
Test tasks are defined with #define_test.
|
244
|
+
|
245
|
+
=The tasks
|
246
|
+
|
247
|
+
|
248
|
+
==default
|
249
|
+
Includes:
|
250
|
+
* check
|
251
|
+
|
252
|
+
==check
|
253
|
+
Includes:
|
254
|
+
* check_version
|
255
|
+
* check_gemspec
|
256
|
+
|
257
|
+
===check_version
|
258
|
+
The gem has a defined version.
|
259
|
+
|
260
|
+
Inside your code you have VERSION-definition you can add with Gem_packer#versions
|
261
|
+
|
262
|
+
This tasks checks, if all VERSION fit to the gem-version.
|
263
|
+
|
264
|
+
Example:
|
265
|
+
mygem_def = Gem_packer.new('mygem', '1.0.0')
|
266
|
+
mygem_def.versions << Mygem::VERSION
|
267
|
+
mygem_def.versions << Mygem::Firstclass::VERSION
|
268
|
+
mygem_def.versions << Mygem::Secondclass::VERSION
|
269
|
+
|
270
|
+
===check_gemspec
|
271
|
+
Makes some tests on the gemspec-definition.
|
272
|
+
* File existence (files, test files, executables
|
273
|
+
|
274
|
+
==gem
|
275
|
+
Build the gem.
|
276
|
+
|
277
|
+
==ftp_rdoc
|
278
|
+
Copy the rdoc-files to a ftp-destination.
|
279
|
+
The destionations must be defined with
|
280
|
+
Gem_packer#add_ftp_connection.
|
281
|
+
|
282
|
+
You can block this task with Gem_packer#public = false.
|
283
|
+
|
284
|
+
==push
|
285
|
+
Push the gem to gemcutter.
|
286
|
+
|
287
|
+
You can block this task with Gem_packer#public = false.
|
288
|
+
=end
|
289
|
+
def build_tasks()
|
290
|
+
|
291
|
+
#Define the namespace for the gem.
|
292
|
+
namespace @name do
|
293
|
+
desc "Run default tasks for #{name}"
|
294
|
+
task :default => :check do
|
295
|
+
#empty, only prerequisites needed
|
296
|
+
end
|
297
|
+
|
298
|
+
desc "Run check tasks for #{name}"
|
299
|
+
task :check => [:check_version, :check_gemspec ] do |t|
|
300
|
+
#empty, only prerequisites needed
|
301
|
+
#~ puts t.comment if @verbose
|
302
|
+
end
|
303
|
+
|
304
|
+
desc "Check version for #{@name}"
|
305
|
+
task :check_version do |t|
|
306
|
+
puts t.comment if @verbose
|
307
|
+
check_version()
|
308
|
+
end
|
309
|
+
|
310
|
+
desc "Check gemspec for #{@name}"
|
311
|
+
task :check_gemspec do |t|
|
312
|
+
puts t.comment if @verbose
|
313
|
+
check_gemspec()
|
314
|
+
end
|
315
|
+
|
316
|
+
desc "Build #{@name}-#{@version}.gem"
|
317
|
+
task :gem do |t|
|
318
|
+
puts t.comment if @verbose
|
319
|
+
Gem::Builder.new(@spec).build
|
320
|
+
end
|
321
|
+
|
322
|
+
=begin
|
323
|
+
Remark 2010-07-20:
|
324
|
+
gem uses ruby 1.9-branch
|
325
|
+
-> Use pik to update all branches
|
326
|
+
=end
|
327
|
+
desc "Install #{@name}-#{@version}.gem"
|
328
|
+
task :install => [:check, :gem ] do |t|
|
329
|
+
puts t.comment if @verbose
|
330
|
+
puts `call gem install #{@name}-#{@version}.gem -l`
|
331
|
+
#~ puts `call pik gem install #{@name}-#{@version}.gem -l`
|
332
|
+
end
|
333
|
+
|
334
|
+
desc "Push documentation to gems.rubypla.net"
|
335
|
+
task :ftp_rdoc do |t|
|
336
|
+
raise BlockError, "Task ftp_rdoc blocked for #{@spec.full_name}" unless @public
|
337
|
+
|
338
|
+
puts t.comment if @verbose
|
339
|
+
gemdir = %x{call gem environment gemdir}.strip
|
340
|
+
|
341
|
+
source = File.join( gemdir, 'doc', @spec.full_name, 'rdoc' )
|
342
|
+
|
343
|
+
raise "#{source} not found" unless File.exist?(source)
|
344
|
+
raise "#{source} no directory " unless File.directory?(source)
|
345
|
+
|
346
|
+
raise "No ftp-connection defined" if @ftp_connections.empty?
|
347
|
+
|
348
|
+
Dir.chdir(source){
|
349
|
+
@ftp_connections.each{|ftp|
|
350
|
+
puts "Upload rdoc to #{ftp.host}/#{ftp.target_dir}"
|
351
|
+
#Copy the data into target dir
|
352
|
+
#The target directory is created if it doesn't exist.
|
353
|
+
Rake::FtpUploader.connect(ftp.target_dir, ftp.host, ftp.account, ftp.password){|uploader|
|
354
|
+
uploader.upload_files('**/*')
|
355
|
+
}
|
356
|
+
}
|
357
|
+
}
|
358
|
+
end #ftp_rdoc
|
359
|
+
|
360
|
+
desc "Push #{@name} gem to gemcutter"
|
361
|
+
task :push => :gem do |t|
|
362
|
+
raise BlockError, "Task push blocked for #{@spec.full_name}" unless @public
|
363
|
+
|
364
|
+
puts t.comment if @verbose
|
365
|
+
puts `call gem push #{@name}-#{@version}.gem`
|
366
|
+
end #push
|
367
|
+
|
368
|
+
desc "Create Links to directory and rdoc for #{@name}"
|
369
|
+
task :links do |t|
|
370
|
+
# Klappt leider nicht auf dir -->
|
371
|
+
gemdir = %x{call gem environment gemdir}.strip
|
372
|
+
mk_link( File.join( gemdir, 'gems', @spec.full_name ),
|
373
|
+
"dir_#{@spec.full_name}.dir.lnk",
|
374
|
+
"#{@name} version #{@version}"
|
375
|
+
)
|
376
|
+
mk_link(File.join( gemdir, 'doc', @spec.full_name, 'rdoc', 'index.html' ),
|
377
|
+
"rdoc_#{@spec.full_name}.lnk",
|
378
|
+
"rdoc #{@spec.name} version #{@spec.version}"
|
379
|
+
)
|
380
|
+
end
|
381
|
+
|
382
|
+
end
|
383
|
+
|
384
|
+
#Tasks outside the namespace
|
385
|
+
task :default => @name
|
386
|
+
task @name => "#{@name}:default"
|
387
|
+
#Add prerequisites
|
388
|
+
TASKLIST.each{|task|
|
389
|
+
task task => "#{@name}:#{task}"
|
390
|
+
}
|
391
|
+
|
392
|
+
end #build_tasks()
|
393
|
+
=begin rdoc
|
394
|
+
Check the version.
|
395
|
+
|
396
|
+
Each value from #versions must be equal to #version.
|
397
|
+
=end
|
398
|
+
def check_version()
|
399
|
+
raise VersionError, "Gemspec#version != Gem_packer#version" unless @spec.version.to_s == @version
|
400
|
+
@versions.each{|version|
|
401
|
+
#fixme --> Name rauszubekommen?
|
402
|
+
#~ puts version.object_id
|
403
|
+
raise VersionError, "#{@version} != #{version}" unless version == @version
|
404
|
+
}
|
405
|
+
end
|
406
|
+
|
407
|
+
=begin rdoc
|
408
|
+
Check the gemspec.
|
409
|
+
=end
|
410
|
+
def check_gemspec()
|
411
|
+
#~ check obligatory fields?
|
412
|
+
files = []
|
413
|
+
|
414
|
+
#Check file existence
|
415
|
+
#spec.files includes testfiles.
|
416
|
+
@spec.files.each{|file|
|
417
|
+
puts "\t#{file} missing" unless File.exist?(file)
|
418
|
+
files << file
|
419
|
+
}
|
420
|
+
@spec.test_files.each{|file|
|
421
|
+
puts "\t#{file} missing" unless File.exist?(file)
|
422
|
+
files << file
|
423
|
+
}
|
424
|
+
@spec.executables.each{|file|
|
425
|
+
puts "\t#{file} missing" unless File.exist?(File.join(@spec.bindir, file))
|
426
|
+
files << File.join(@spec.bindir, file)
|
427
|
+
}
|
428
|
+
files.sort!
|
429
|
+
files.uniq!
|
430
|
+
|
431
|
+
#~ fixme: compare files with manifest.
|
432
|
+
#~ puts files.to_yaml
|
433
|
+
end
|
434
|
+
|
435
|
+
=begin rdoc
|
436
|
+
Define tests.
|
437
|
+
=end
|
438
|
+
def define_test( testdir = "unittest", glob = FileList['test*.rb'] )
|
439
|
+
|
440
|
+
raise ArgumentError, "Testdirectory #{testdir} missing" unless File.exist?(testdir)
|
441
|
+
raise ArgumentError, "Testdirectory #{testdir} missing" unless File.directory?(testdir)
|
442
|
+
|
443
|
+
lib = ("../" * (testdir.count('/') + 1) ) + @spec.require_path
|
444
|
+
raise ArgumentError, "Require path #{@spec.require_path} missing from #{testdir}" unless File.exist?("#{testdir}/#{lib}")
|
445
|
+
raise ArgumentError, "Require path #{@spec.require_path} missing from #{testdir}" unless File.directory?("#{testdir}/#{lib}")
|
446
|
+
|
447
|
+
#Check if test files exist
|
448
|
+
Dir.chdir(testdir){
|
449
|
+
raise ArgumentError, "Test files missing in #{testdir}" unless glob.existing.size > 0
|
450
|
+
}
|
451
|
+
|
452
|
+
#Define the test tasks
|
453
|
+
testcase = Rake::TestTask.new("#{@name}:test") do |t|
|
454
|
+
t.dir = testdir #possible with 'knut_tools/rake/testtask.rb'
|
455
|
+
#Get 'lib' directory relative to test directory.
|
456
|
+
t.libs << lib
|
457
|
+
t.test_files = glob
|
458
|
+
t.verbose = true
|
459
|
+
end
|
460
|
+
|
461
|
+
task :test => "#{@name}:test"
|
462
|
+
|
463
|
+
testcase
|
464
|
+
end #define_test
|
465
|
+
|
466
|
+
end
|
467
|
+
|
468
|
+
=begin rdoc
|
469
|
+
Tasks outside the namespace.
|
470
|
+
Define the titles.
|
471
|
+
=end
|
472
|
+
desc "Run default tasks for all gem-definitions"
|
473
|
+
task :default
|
474
|
+
desc "Check all versions"
|
475
|
+
task :check_version
|
476
|
+
desc "Check all gemspecs"
|
477
|
+
task :check_gemspec
|
478
|
+
|
479
|
+
=begin
|
480
|
+
Helper tasks to build the readmes.
|
481
|
+
=end
|
482
|
+
begin
|
483
|
+
require 'creole/creole2doc' #needed for readme.html, readme.txt
|
484
|
+
rescue
|
485
|
+
#define dummy class
|
486
|
+
class Creole_document
|
487
|
+
def save(filename)
|
488
|
+
puts "Error: Use of Creole_document without docgenerator-gem"
|
489
|
+
end
|
490
|
+
end
|
491
|
+
end
|
492
|
+
#Build the html-readme from creole-source
|
493
|
+
rule '.html' => '.creole' do |t|
|
494
|
+
doc = Creole_document.new()
|
495
|
+
File.open(t.source){|f| doc << f }
|
496
|
+
doc.save(t.name)
|
497
|
+
end
|
498
|
+
#Build the text-readme from creole-source
|
499
|
+
rule '.txt' => '.creole' do |t|
|
500
|
+
doc = Creole_document.new()
|
501
|
+
File.open(t.source){|f| doc << f }
|
502
|
+
doc.save(t.name)
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
if $0 == __FILE__
|
507
|
+
#~ puts Gem_packer::Template
|
508
|
+
|
509
|
+
app = Rake.application
|
510
|
+
#~ app[:check_version].invoke
|
511
|
+
#~ app['test'].invoke
|
512
|
+
#~ app[:default].invoke
|
513
|
+
end
|
514
|
+
|
515
|
+
__END__
|
516
|
+
|
517
|
+
require "win32/shortcut"
|
518
|
+
def mk_link( target, linkname, descr )
|
519
|
+
if File.exist?(target)
|
520
|
+
s = Win32::Shortcut.new(linkname)
|
521
|
+
s.description = descr
|
522
|
+
s.path = target
|
523
|
+
s.show_cmd = Win32::Shortcut::SHOWNORMAL
|
524
|
+
s.working_directory = "C:\\"
|
525
|
+
s.save
|
526
|
+
puts "Build link to #{s.path}"
|
527
|
+
else
|
528
|
+
puts "No link created to #{target}"
|
529
|
+
end
|
530
|
+
end
|
531
|
+
|
532
|
+
desc "Prepare the readmes"
|
533
|
+
task :readme => [] do
|
534
|
+
puts "Build readmes"
|
535
|
+
readme = Creole_document.new
|
536
|
+
readme << DESCRIPTION
|
537
|
+
readme.save('readme.txt')
|
538
|
+
readme.save('readme.html')
|
539
|
+
end
|
540
|
+
|
541
|
+
|
542
|
+
|
543
|
+
#
|
544
|
+
#gem fr�gt bei uninstall gerne nach (abh�ngigkeiten, welche version....)
|
545
|
+
#rake-prozess wartet dann auf user-eingabe.
|
546
|
+
#
|
547
|
+
#~ #desc "Uninstall the gem first"
|
548
|
+
#~ task :uninstall do
|
549
|
+
#~ puts "Vorsicht vor R�ckfragen"
|
550
|
+
#~ puts `call gem uninstall #{SPEC.name} --version #{SPEC.version}`
|
551
|
+
#~ end
|