RailsTop 0.0.1
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 +2 -0
- data/README +78 -0
- data/Rakefile +49 -0
- data/bin/railstop +49 -0
- data/config/default.yml +16 -0
- data/lib/railstop.rb +199 -0
- data/test/test_railstop.rb +32 -0
- metadata +60 -0
data/CHANGELOG
ADDED
data/README
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
<b>Tool parade scans your system for Ruby Gems and Rails plugins and uploads the result to a central server</b>
|
|
2
|
+
|
|
3
|
+
This data is used for analysis on Rubyclub.com.ua to generate
|
|
4
|
+
public charts of the most active plugins and gems.
|
|
5
|
+
You have full control over how and what data is submitted
|
|
6
|
+
|
|
7
|
+
Project Home page: http://rubyclub.com.ua/
|
|
8
|
+
|
|
9
|
+
==Why do this?
|
|
10
|
+
|
|
11
|
+
* Share your installed gems/plugins with others. Get ideas of what
|
|
12
|
+
libraries you might want to use based on others credentials.
|
|
13
|
+
|
|
14
|
+
* Ensure that the authors of the plugin/gems get the credit they deserve.
|
|
15
|
+
* Gem builders / plugin authors - see how many developers use your gem, which version etc.
|
|
16
|
+
|
|
17
|
+
* Lowers the barrier for people to report what libraries they are using. It is
|
|
18
|
+
potentially more informative than pure download stats.
|
|
19
|
+
|
|
20
|
+
* Allows the system to make intelligent recommendations of plugins you may
|
|
21
|
+
also be interested in / alternatives. (in the future)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
==Usage
|
|
25
|
+
|
|
26
|
+
Run this on your development machine only. It's always best to set it to where you
|
|
27
|
+
develop your Rails application. Scanning for plugins may take a very long time
|
|
28
|
+
if you have a large number projects.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
Standard operation:
|
|
32
|
+
railstop
|
|
33
|
+
|
|
34
|
+
Help
|
|
35
|
+
railstop help
|
|
36
|
+
|
|
37
|
+
Setup
|
|
38
|
+
railstop setup
|
|
39
|
+
|
|
40
|
+
Config (views the config)
|
|
41
|
+
railstop config
|
|
42
|
+
|
|
43
|
+
Debug
|
|
44
|
+
railstop debug
|
|
45
|
+
|
|
46
|
+
== Tips
|
|
47
|
+
|
|
48
|
+
Lets say you are working on a super top secret library and you don't want
|
|
49
|
+
this to be published.
|
|
50
|
+
Just add it to the ignore section in your railstop.yml config (usually
|
|
51
|
+
located in your home directory):
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Example:
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
ignore:
|
|
58
|
+
gems: my_private_gem,CVS
|
|
59
|
+
plugins: my_secret_project
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
If you know you don't really use a plugin / gem also feel free to use
|
|
63
|
+
ignore list.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
==Limitations
|
|
67
|
+
|
|
68
|
+
Removal of a gem or plugin is not currently reflected.
|
|
69
|
+
You need to remove it using the web based interface if desired.
|
|
70
|
+
|
|
71
|
+
This is true in the case of ignore filters if the gem/plugin to ignore has
|
|
72
|
+
already been registered in a previous scan.
|
|
73
|
+
|
|
74
|
+
Of course just because the plugin / gem is installed on your system is doesn't
|
|
75
|
+
mean you are using it all the time if at all. Currently this tool doesn't
|
|
76
|
+
make allowances for distinguishing this matter.
|
|
77
|
+
There is however plenty of scope to improve the algorithms and scanning techniques
|
|
78
|
+
in place. Feel free to drop me a line with suggestions.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
Gem::manage_gems
|
|
3
|
+
require 'rake/gempackagetask'
|
|
4
|
+
require 'rake/rdoctask'
|
|
5
|
+
|
|
6
|
+
PKG_FILES = FileList[
|
|
7
|
+
"Rakefile", "README","CHANGELOG",
|
|
8
|
+
"config/**/*",
|
|
9
|
+
"test/**/*",
|
|
10
|
+
"lib/**/*.rb",
|
|
11
|
+
"bin/**/*"
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
spec = Gem::Specification.new do |s|
|
|
15
|
+
s.name = "RailsTop"
|
|
16
|
+
s.version = "0.0.1"
|
|
17
|
+
s.author = "Voloshin Ruslan"
|
|
18
|
+
s.email = "rebisall@googlemail.com"
|
|
19
|
+
s.homepage = "http://rubyclub.com.ua/"
|
|
20
|
+
s.platform = Gem::Platform::RUBY
|
|
21
|
+
s.summary = "Get your gems and plugins for rubyclub top"
|
|
22
|
+
s.files = PKG_FILES
|
|
23
|
+
s.require_path = "lib"
|
|
24
|
+
s.autorequire = "name"
|
|
25
|
+
s.test_files = FileList["{test}/**/*test.rb"].to_a
|
|
26
|
+
s.has_rdoc = true
|
|
27
|
+
s.extra_rdoc_files = ["README"]
|
|
28
|
+
s.executables = ['railstop']
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Genereate the RDoc documentation
|
|
33
|
+
Rake::RDocTask.new { |rdoc|
|
|
34
|
+
rdoc.rdoc_dir = 'doc'
|
|
35
|
+
rdoc.title = "Rails Top"
|
|
36
|
+
rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
|
37
|
+
rdoc.rdoc_files.include('README')
|
|
38
|
+
rdoc.rdoc_files.include(Dir.glob("lib/**/*.rb") )
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
|
43
|
+
pkg.need_tar = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
task :default => "pkg/#{spec.name}-#{spec.version}.gem" do
|
|
47
|
+
puts "generated latest version"
|
|
48
|
+
end
|
|
49
|
+
|
data/bin/railstop
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
|
|
3
|
+
|
|
4
|
+
require 'railstop'
|
|
5
|
+
|
|
6
|
+
PROGRAM = File::basename $0
|
|
7
|
+
mode = ARGV.shift
|
|
8
|
+
@debug = false
|
|
9
|
+
|
|
10
|
+
puts "Ruby and Rails Top"
|
|
11
|
+
puts "=-=-=-=-=-=-=-=-=-=-=-=-=-"
|
|
12
|
+
puts "\"#{PROGRAM} help\" for help"
|
|
13
|
+
|
|
14
|
+
case mode
|
|
15
|
+
when %r/help/
|
|
16
|
+
puts File.open(File.expand_path(File.dirname(__FILE__) + "/../README")).read
|
|
17
|
+
exit
|
|
18
|
+
when %r/setup/
|
|
19
|
+
RailsTop.setup
|
|
20
|
+
exit
|
|
21
|
+
when %r/config/
|
|
22
|
+
@tp = RailsTop.new
|
|
23
|
+
puts "Reading config located in #{RailsTop::CONFIG}"
|
|
24
|
+
puts @tp.config.to_yaml
|
|
25
|
+
exit
|
|
26
|
+
when %r/debug/
|
|
27
|
+
@debug = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@tp = RailsTop.new
|
|
31
|
+
p @tp.config if @debug
|
|
32
|
+
|
|
33
|
+
puts "Scanning system for: "
|
|
34
|
+
print "Gems... "
|
|
35
|
+
@tp.scan_for_gems
|
|
36
|
+
p @tp.gemslist if @debug
|
|
37
|
+
puts 'Done'
|
|
38
|
+
puts "Plugins.. (this may take a while) "
|
|
39
|
+
@tp.scan_for_plugins
|
|
40
|
+
p @tp.pluginslist if @debug
|
|
41
|
+
puts "Finished"
|
|
42
|
+
|
|
43
|
+
@tp.view_scan
|
|
44
|
+
|
|
45
|
+
@tp.get_login_credentials
|
|
46
|
+
puts "Please wait. Authenticating and uploading...."
|
|
47
|
+
@tp.upload
|
|
48
|
+
puts "The result of your upload can be viewed at http://#{@tp.domain} from your profile page."
|
|
49
|
+
puts "Thank you for using Rails Top"
|
data/config/default.yml
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
upload:
|
|
2
|
+
domain: rubyclub.com.ua
|
|
3
|
+
username:
|
|
4
|
+
password:
|
|
5
|
+
|
|
6
|
+
paths:
|
|
7
|
+
plugins: ~/dev;~/sandbox
|
|
8
|
+
|
|
9
|
+
transmit:
|
|
10
|
+
gem_version_numbers: true
|
|
11
|
+
plugin_numbers: true
|
|
12
|
+
|
|
13
|
+
# Regex's allowed e.g. prefix_*
|
|
14
|
+
ignore:
|
|
15
|
+
gems: my_private_gem,CVS
|
|
16
|
+
plugins: my_secret_project
|
data/lib/railstop.rb
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
def Kernel.is_windows?
|
|
7
|
+
processor, platform, *rest = RUBY_PLATFORM.split("-")
|
|
8
|
+
platform == 'mswin32'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# See README for full documentation
|
|
13
|
+
#
|
|
14
|
+
#TODO: Room for some refactoring, perhaps use of exceptions in places (make it easier to catch and test desired behaviours)
|
|
15
|
+
class RailsTop
|
|
16
|
+
# :stopdoc:
|
|
17
|
+
VERSION = "0.0.1"
|
|
18
|
+
HOME = ENV["HOME"] || ENV["HOMEPATH"] || File::expand_path("~")
|
|
19
|
+
CONFIG = File::join HOME, ".railstop.yml"
|
|
20
|
+
DEFAULT_CONFIG = File.expand_path("#{__FILE__}/../../config/default.yml")
|
|
21
|
+
|
|
22
|
+
# :startdoc:
|
|
23
|
+
attr_accessor :config
|
|
24
|
+
attr_reader :pluginslist
|
|
25
|
+
attr_reader :plugin_descriptions
|
|
26
|
+
|
|
27
|
+
attr_reader :gemslist
|
|
28
|
+
|
|
29
|
+
attr_reader :username
|
|
30
|
+
attr_reader :password
|
|
31
|
+
attr_reader :domain
|
|
32
|
+
|
|
33
|
+
def initialize(options = {})
|
|
34
|
+
return if options[:skip]
|
|
35
|
+
|
|
36
|
+
begin
|
|
37
|
+
@config = YAML.load_file(CONFIG)
|
|
38
|
+
rescue Errno::ENOENT
|
|
39
|
+
puts "No configuration file detected. Entering first time setup."
|
|
40
|
+
puts
|
|
41
|
+
setup
|
|
42
|
+
end
|
|
43
|
+
@username = @config['upload']['username']
|
|
44
|
+
@password = @config['upload']['password']
|
|
45
|
+
@domain = @config['upload']['domain']
|
|
46
|
+
@plugin_descriptions = {}
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.setup
|
|
51
|
+
new(:skip => true).setup
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def setup
|
|
55
|
+
puts "Enter the path where you develop your Rails applications."
|
|
56
|
+
puts "Separated by ; if there is more than one e.g. ~/dev;~/sandbox"
|
|
57
|
+
print "> Rails plugin scan path (#{HOME}): "
|
|
58
|
+
path = gets.chomp!
|
|
59
|
+
path = path == '' ? HOME : path
|
|
60
|
+
@config = YAML.load_file(DEFAULT_CONFIG)
|
|
61
|
+
@config['paths']['plugins'] = path
|
|
62
|
+
begin
|
|
63
|
+
open(CONFIG, "w") { |f| f.write @config.to_yaml }
|
|
64
|
+
rescue Errno::ENOENT
|
|
65
|
+
puts "Unable to open #{CONFIG} for writing."
|
|
66
|
+
exit
|
|
67
|
+
end
|
|
68
|
+
puts "SETUP COMPLETE. Configuration stored in: #{CONFIG}"
|
|
69
|
+
puts
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def scan_for_gems
|
|
74
|
+
@gemslist = Kernel.is_windows? ? `cmd /c gem list` : `gem list`
|
|
75
|
+
@gemslist = "#{@gemslist.grep(/^[a-zA-Z]/)}\n"
|
|
76
|
+
remove_bracketed_info!(@gemlist) unless @config['transmit']['gem_version_numbers']
|
|
77
|
+
apply_ignore_filters!(@gemslist)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def scan_for_plugins
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
scores = Hash.new(0)
|
|
85
|
+
for path in @config['paths']['plugins'].split(';')
|
|
86
|
+
scanpath = File.expand_path(path.to_s.strip)
|
|
87
|
+
if FileTest.exist?(scanpath)
|
|
88
|
+
|
|
89
|
+
Dir["#{scanpath}/**/vendor/plugins/**"].each{|f|
|
|
90
|
+
scores[File.basename(f)] += 1
|
|
91
|
+
readme = File.expand_path("#{f}/README")
|
|
92
|
+
if FileTest.exist?(readme)
|
|
93
|
+
@plugin_descriptions[File.basename(f)] ||= File.open(readme).read
|
|
94
|
+
end
|
|
95
|
+
}
|
|
96
|
+
else
|
|
97
|
+
puts "Warning / Notice: Plugin scan path: #{path} cannot be read"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
@pluginslist = scores.collect{|name,score| "#{name} (#{score})"}.join("\n")+"\n"
|
|
101
|
+
|
|
102
|
+
remove_bracketed_info!(@pluginslist) unless @config['transmit']['plugin_numbers']
|
|
103
|
+
apply_ignore_filters!(@pluginslist)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def view_scan
|
|
107
|
+
print "Would you like to review the list of plugins and gems details that will be uploaded before continuing? (Y/N): "
|
|
108
|
+
return unless gets =~ /y/i
|
|
109
|
+
print_gem_and_plugin_info
|
|
110
|
+
|
|
111
|
+
puts "If you wish filter out certain results you may do so now by editing #{CONFIG}"
|
|
112
|
+
puts ""
|
|
113
|
+
|
|
114
|
+
ok = false
|
|
115
|
+
|
|
116
|
+
while !ok
|
|
117
|
+
|
|
118
|
+
print "If you have modified the configuration file hit yes for your changes to take effect (Y/N): "
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if gets =~ /y/i
|
|
122
|
+
@config = YAML.load_file(CONFIG)
|
|
123
|
+
remove_bracketed_info!(@pluginslist) unless @config['transmit']['plugin_numbers']
|
|
124
|
+
apply_ignore_filters!(@pluginslist)
|
|
125
|
+
remove_bracketed_info!(@gemlist) unless @config['transmit']['gem_version_numbers']
|
|
126
|
+
apply_ignore_filters!(@gemslist)
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
print_gem_and_plugin_info
|
|
130
|
+
puts "Displayed are the results that will be now uploaded."
|
|
131
|
+
puts "You may go back and edit the configuration file some more or..."
|
|
132
|
+
print "If you are happy with the results hit yes. (Y/N:)"
|
|
133
|
+
ok = true if gets =~ /y/i
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def print_gem_and_plugin_info
|
|
138
|
+
puts "Gems Found"
|
|
139
|
+
puts "---------------------------------------"
|
|
140
|
+
puts @gemslist
|
|
141
|
+
puts "Plugins Found"
|
|
142
|
+
puts "---------------------------------------"
|
|
143
|
+
puts @pluginslist.split("\n").sort
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def get_login_credentials
|
|
147
|
+
return if "#{@username}".strip.chomp != '' && "#{@password}".strip.chomp !=''
|
|
148
|
+
|
|
149
|
+
puts "Please login to Working With Rails to continue upload"
|
|
150
|
+
print "> Username: "
|
|
151
|
+
@username = gets.chomp!
|
|
152
|
+
print "> Password: "
|
|
153
|
+
@password = get_password
|
|
154
|
+
puts ""
|
|
155
|
+
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def upload
|
|
159
|
+
res = Net::HTTP.post_form(URI.parse("http://#{@domain}/rubygems/upload"),
|
|
160
|
+
{'login'=>@username, 'password'=>@password, 'list' => @gemslist})
|
|
161
|
+
puts "Gem upload response: #{res.body}"
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
post_fields = {'login'=>@username, 'password'=>@password, 'list' => @pluginslist}
|
|
165
|
+
@plugin_descriptions.each{|name, description| post_fields["readmes[#{name}]"] = description}
|
|
166
|
+
|
|
167
|
+
res = Net::HTTP.post_form(URI.parse("http://#{@domain}/railsplugins/upload"),
|
|
168
|
+
post_fields)
|
|
169
|
+
puts "Plugin upload response: #{res.body}"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
def get_password
|
|
176
|
+
if Kernel.is_windows?
|
|
177
|
+
return gets.chomp!
|
|
178
|
+
else
|
|
179
|
+
# on a non-windows box we can hide input for the password
|
|
180
|
+
`stty -echo`
|
|
181
|
+
begin
|
|
182
|
+
out = STDIN.gets.chomp
|
|
183
|
+
ensure
|
|
184
|
+
`stty echo`
|
|
185
|
+
end
|
|
186
|
+
return out
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def remove_bracketed_info!(string)
|
|
193
|
+
string.gsub!(/\([^\)]+\)/,'')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def apply_ignore_filters!(string)
|
|
197
|
+
string.gsub!(/#{config['ignore']['plugins'].split(',').collect{|i| "^#{i.strip}.*\n"}.join('|')}/,'')
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'lib/railstop'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TestRailsTop < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@tp = RailsTop.new
|
|
9
|
+
@tp.config['paths']['plugins'] = "#{File.expand_path(File.dirname(__FILE__))}/fixtures"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_plugin_path_scan
|
|
13
|
+
@tp.scan_for_plugins
|
|
14
|
+
assert_equal "acts_as_a (1)\nacts_as_b (1)\nacts_as_c (1)\n", @tp.pluginslist
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_ignore_filters_for_plugin
|
|
18
|
+
@tp.config['ignore']['plugins'] = "acts_as_b,acts_as_c\n"
|
|
19
|
+
@tp.scan_for_plugins
|
|
20
|
+
assert_equal "acts_as_a (1)\n", @tp.pluginslist
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_filter_version_numbers
|
|
25
|
+
@tp.config['transmit']['gem_version_numbers'] = false
|
|
26
|
+
gemslist = "gem a (1.0)\ngem b (2.0)\ngem c (2.1,2.01)\n"
|
|
27
|
+
@tp.send('remove_bracketed_info!',gemslist)
|
|
28
|
+
assert_equal "gem a \ngem b \ngem c \n", gemslist
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: RailsTop
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Voloshin Ruslan
|
|
8
|
+
autorequire: name
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain:
|
|
11
|
+
date: 2010-01-09 00:00:00 +02:00
|
|
12
|
+
default_executable: railstop
|
|
13
|
+
dependencies: []
|
|
14
|
+
|
|
15
|
+
description:
|
|
16
|
+
email: rebisall@gmail.com
|
|
17
|
+
executables:
|
|
18
|
+
- railstop
|
|
19
|
+
extensions: []
|
|
20
|
+
|
|
21
|
+
extra_rdoc_files:
|
|
22
|
+
- README
|
|
23
|
+
files:
|
|
24
|
+
- Rakefile
|
|
25
|
+
- README
|
|
26
|
+
- CHANGELOG
|
|
27
|
+
- config/default.yml
|
|
28
|
+
- test/test_railstop.rb
|
|
29
|
+
- lib/railstop.rb
|
|
30
|
+
- bin/railstop
|
|
31
|
+
has_rdoc: true
|
|
32
|
+
homepage: http://rubyclub.com.ua/
|
|
33
|
+
licenses: []
|
|
34
|
+
|
|
35
|
+
post_install_message:
|
|
36
|
+
rdoc_options: []
|
|
37
|
+
|
|
38
|
+
require_paths:
|
|
39
|
+
- lib
|
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">"
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: 0.0.0
|
|
45
|
+
version:
|
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
47
|
+
requirements:
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: "0"
|
|
51
|
+
version:
|
|
52
|
+
requirements: []
|
|
53
|
+
|
|
54
|
+
rubyforge_project:
|
|
55
|
+
rubygems_version: 1.3.5
|
|
56
|
+
signing_key:
|
|
57
|
+
specification_version: 1
|
|
58
|
+
summary: Get your gems and plugins list for RubyClub top
|
|
59
|
+
test_files: []
|
|
60
|
+
|