sashimi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +57 -0
- data/MIT-LICENSE +20 -0
- data/README +73 -0
- data/Rakefile +22 -0
- data/bin/sashimi +8 -0
- data/lib/sashimi/commands.rb +183 -0
- data/lib/sashimi/plugin.rb +76 -0
- data/lib/sashimi/repositories/abstract_repository.rb +231 -0
- data/lib/sashimi/repositories/git_repository.rb +16 -0
- data/lib/sashimi/repositories/svn_repository.rb +16 -0
- data/lib/sashimi/repositories.rb +1 -0
- data/lib/sashimi.rb +11 -0
- data/sashimi.gemspec +17 -0
- data/setup.rb +1585 -0
- data/test/test_helper.rb +73 -0
- data/test/unit/plugin_test.rb +38 -0
- data/test/unit/repositories/abstract_repository_test.rb +132 -0
- data/test/unit/repositories/git_repository_test.rb +8 -0
- data/test/unit/repositories/svn_repository_test.rb +8 -0
- metadata +83 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
* *v0.1.0*
|
2
|
+
|
3
|
+
* Print on the stdout the plugin name on each command execution
|
4
|
+
|
5
|
+
* Fixed shell help output in commands.rb: make clear each command accepts multiple params. Deleted duplicated Update class from commands.rb.
|
6
|
+
|
7
|
+
* Fixed sashimi.gemspec: sashimi executable is now available after gem setup
|
8
|
+
|
9
|
+
* Made AbstractRepository#remove_hidden_folders platform independent
|
10
|
+
|
11
|
+
* Fixed loading in sashimi
|
12
|
+
|
13
|
+
* Fixed lib loading in sashimi.rb
|
14
|
+
|
15
|
+
* Added setup.rb
|
16
|
+
|
17
|
+
* Added PluginNotFound to improve OOP in exceptions handling
|
18
|
+
|
19
|
+
* Added version.rb
|
20
|
+
|
21
|
+
* Added installation instructions, examples and copyright to README [#9 state:resolved]
|
22
|
+
|
23
|
+
* Created gemspec file [#8 state:resolved]
|
24
|
+
|
25
|
+
* Added MIT-LICENSE [#10 state:resolved]
|
26
|
+
|
27
|
+
* Add an installed plugin to a Rails app [#7 state:resolved]
|
28
|
+
|
29
|
+
* Show plugin summary in list command [#6 state:resolved]
|
30
|
+
|
31
|
+
* Improved tests for Plugin#about
|
32
|
+
|
33
|
+
* Cache summary stored in plugin about.yml [#5 state:resolved]
|
34
|
+
|
35
|
+
* Plugin serialization [#4 state:resolved]
|
36
|
+
|
37
|
+
* List all installed plugins [#3 state:resolved]
|
38
|
+
|
39
|
+
* Update an installed plugin [#1 state:resolved]
|
40
|
+
|
41
|
+
* Refactored Plugin and AbstractRepository to separate class responsabilities
|
42
|
+
|
43
|
+
* Remove a plugin from cache when uninstalled
|
44
|
+
|
45
|
+
* Created a plugins cache to store the repository type (svn or git)
|
46
|
+
|
47
|
+
* Improved shell commands help
|
48
|
+
|
49
|
+
* Basic plugin uninstall process
|
50
|
+
|
51
|
+
* Basic plugin install process
|
52
|
+
|
53
|
+
* Introducing Plugin, AbstractRepository, SvnRepository and GitRepository
|
54
|
+
|
55
|
+
* Adding Rakefile
|
56
|
+
|
57
|
+
* Adding CHANGELOG
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Luca Guidi
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
Sashimi
|
2
|
+
=======
|
3
|
+
|
4
|
+
Sashimi is a Rails plugins manager.
|
5
|
+
It allows to install your favourite plugins in a local repository and add them to your Rails apps.
|
6
|
+
The main goal is to allow the plugins offline installation.
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
Installation
|
11
|
+
============
|
12
|
+
|
13
|
+
$ (sudo) gem install jodosha-sashimi --source=http://gems.github.com
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
Usage
|
18
|
+
=====
|
19
|
+
|
20
|
+
Install a plugin from a subversion URL:
|
21
|
+
$ sashimi install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder
|
22
|
+
|
23
|
+
Install a plugin from a git URL:
|
24
|
+
$ sashimi install git://github.com/jodosha/click-to-globalize.git
|
25
|
+
|
26
|
+
Uninstall a plugin:
|
27
|
+
$ sashimi uninstall continuous_builder
|
28
|
+
|
29
|
+
Update a plugin:
|
30
|
+
$ sashimi update click-to-globalize
|
31
|
+
|
32
|
+
List all installed plugins:
|
33
|
+
$ sashimi list
|
34
|
+
|
35
|
+
Add installed plugin(s) to a Rails app:
|
36
|
+
$ sashimi add click-to-globalize
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
Known And Common Issues
|
41
|
+
=======================
|
42
|
+
|
43
|
+
* When add a plugin to an app, make sure your current directory is the rails root.
|
44
|
+
|
45
|
+
* Only Subversion and Git repositories are currently supported.
|
46
|
+
|
47
|
+
|
48
|
+
Contribute
|
49
|
+
==========
|
50
|
+
|
51
|
+
* Check out the code and test it:
|
52
|
+
$ git clone git://github.com/jodosha/sashimi.git
|
53
|
+
$ rake
|
54
|
+
|
55
|
+
* Create a ticket to: http://sushistar.lighthouseapp.com
|
56
|
+
|
57
|
+
* Create a patch and add as attachement to the ticket.
|
58
|
+
|
59
|
+
|
60
|
+
Credits
|
61
|
+
=======
|
62
|
+
|
63
|
+
Partially inspired to RaPT[http://rapt.rubyforge.org/].
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
Home Page
|
68
|
+
=========
|
69
|
+
http://lucaguidi.com/pages/sashimi
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
Copyright (c) 2008 Luca Guidi - http://lucaguidi.com, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the sashimi gem.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the sashimi gem.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'Sashimi'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
data/bin/sashimi
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module Sashimi
|
4
|
+
module Commands
|
5
|
+
class Command
|
6
|
+
attr_reader :script_name
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@script_name = File.basename($0)
|
10
|
+
end
|
11
|
+
|
12
|
+
def options
|
13
|
+
OptionParser.new do |o|
|
14
|
+
o.set_summary_indent(' ')
|
15
|
+
o.banner = "Usage: #{@script_name} [OPTIONS] command"
|
16
|
+
o.define_head "Rails plugin manager."
|
17
|
+
|
18
|
+
o.separator ""
|
19
|
+
o.separator "GENERAL OPTIONS"
|
20
|
+
|
21
|
+
o.on("-v", "--verbose", "Turn on verbose output.") { |$verbose| }
|
22
|
+
o.on("-h", "--help", "Show this help message.") { puts o; exit }
|
23
|
+
|
24
|
+
o.separator ""
|
25
|
+
o.separator "COMMANDS"
|
26
|
+
|
27
|
+
o.separator " install Install plugin(s) from known URL(s)."
|
28
|
+
o.separator " uninstall Uninstall plugin(s) from local repository."
|
29
|
+
o.separator " update Update installed plugin(s)."
|
30
|
+
o.separator " list List all installed plugins."
|
31
|
+
o.separator " add Add installed plugin(s) to a Rails app."
|
32
|
+
|
33
|
+
o.separator ""
|
34
|
+
o.separator "EXAMPLES"
|
35
|
+
o.separator " Install a plugin from a subversion URL:"
|
36
|
+
o.separator " #{@script_name} install http://dev.rubyonrails.com/svn/rails/plugins/continuous_builder\n"
|
37
|
+
o.separator " Install a plugin from a git URL:"
|
38
|
+
o.separator " #{@script_name} install git://github.com/jodosha/click-to-globalize.git\n"
|
39
|
+
o.separator " Uninstall a plugin:"
|
40
|
+
o.separator " #{@script_name} uninstall continuous_builder\n"
|
41
|
+
o.separator " Update a plugin:"
|
42
|
+
o.separator " #{@script_name} update click-to-globalize\n"
|
43
|
+
o.separator " List all installed plugins:"
|
44
|
+
o.separator " #{@script_name} list\n"
|
45
|
+
o.separator " Add installed plugin(s) to a Rails app:"
|
46
|
+
o.separator " #{@script_name} add click-to-globalize\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse!(args=ARGV)
|
51
|
+
general, sub = split_args(args)
|
52
|
+
options.parse!(general)
|
53
|
+
|
54
|
+
command = general.shift
|
55
|
+
if command =~ /^(install|uninstall|update|list|add)$/
|
56
|
+
command = Commands.const_get(command.capitalize).new(self)
|
57
|
+
command.parse!(sub)
|
58
|
+
else
|
59
|
+
puts "Unknown command: #{command}"
|
60
|
+
puts options
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def split_args(args)
|
66
|
+
left = []
|
67
|
+
left << args.shift while args[0] and args[0] =~ /^-/
|
68
|
+
left << args.shift if args[0]
|
69
|
+
return [left, args]
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.parse!(args=ARGV)
|
73
|
+
Command.new.parse!(args)
|
74
|
+
rescue Exception => e
|
75
|
+
puts e.message
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class Install
|
81
|
+
def initialize(base_command)
|
82
|
+
@base_command = base_command
|
83
|
+
end
|
84
|
+
|
85
|
+
def options
|
86
|
+
OptionParser.new do |o|
|
87
|
+
o.set_summary_indent(' ')
|
88
|
+
o.banner = "Usage: #{@base_command.script_name} install URL [URL2, URL3]"
|
89
|
+
o.define_head "Install plugin(s) from known URL(s)."
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse!(args)
|
94
|
+
options.parse!(args)
|
95
|
+
args.each do |url|
|
96
|
+
Plugin.new(nil, url).install
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class Uninstall
|
102
|
+
def initialize(base_command)
|
103
|
+
@base_command = base_command
|
104
|
+
end
|
105
|
+
|
106
|
+
def options
|
107
|
+
OptionParser.new do |o|
|
108
|
+
o.set_summary_indent(' ')
|
109
|
+
o.banner = "Usage: #{@base_command.script_name} uninstall PLUGIN [PLUGIN2, PLUGIN3]"
|
110
|
+
o.define_head "Uninstall plugin(s) from local repository."
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def parse!(args)
|
115
|
+
options.parse!(args)
|
116
|
+
args.each do |name|
|
117
|
+
Plugin.new(name).uninstall
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class Update
|
123
|
+
def initialize(base_command)
|
124
|
+
@base_command = base_command
|
125
|
+
end
|
126
|
+
|
127
|
+
def options
|
128
|
+
OptionParser.new do |o|
|
129
|
+
o.set_summary_indent(' ')
|
130
|
+
o.banner = "Usage: #{@base_command.script_name} update PLUGIN [PLUGIN2, PLUGIN3]"
|
131
|
+
o.define_head "Update installed plugin(s)."
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse!(args)
|
136
|
+
options.parse!(args)
|
137
|
+
args.each do |name|
|
138
|
+
Plugin.new(name).update
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class List
|
144
|
+
def initialize(base_command)
|
145
|
+
@base_command = base_command
|
146
|
+
end
|
147
|
+
|
148
|
+
def options
|
149
|
+
OptionParser.new do |o|
|
150
|
+
o.set_summary_indent(' ')
|
151
|
+
o.banner = "Usage: #{@base_command.script_name} list"
|
152
|
+
o.define_head "List all installed plugins."
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def parse!(args)
|
157
|
+
options.parse!(args)
|
158
|
+
puts Plugin.list
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class Add
|
163
|
+
def initialize(base_command)
|
164
|
+
@base_command = base_command
|
165
|
+
end
|
166
|
+
|
167
|
+
def options
|
168
|
+
OptionParser.new do |o|
|
169
|
+
o.set_summary_indent(' ')
|
170
|
+
o.banner = "Usage: #{@base_command.script_name} add PLUGIN"
|
171
|
+
o.define_head "Add installed plugin(s) to a Rails app."
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def parse!(args)
|
176
|
+
options.parse!(args)
|
177
|
+
args.each do |name|
|
178
|
+
Plugin.new(name).add
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Sashimi
|
2
|
+
class Plugin
|
3
|
+
attr_reader :url, :name
|
4
|
+
|
5
|
+
def initialize(name, url = '')
|
6
|
+
@url = URI::parse(url).to_s
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
# Install the plugin
|
11
|
+
def install
|
12
|
+
repository.install
|
13
|
+
end
|
14
|
+
|
15
|
+
# Uninstall the plugin
|
16
|
+
def uninstall
|
17
|
+
repository.uninstall
|
18
|
+
end
|
19
|
+
|
20
|
+
# Update the plugin
|
21
|
+
def update
|
22
|
+
repository.update
|
23
|
+
end
|
24
|
+
|
25
|
+
# Add to a Rails app
|
26
|
+
def add
|
27
|
+
repository.add
|
28
|
+
end
|
29
|
+
|
30
|
+
def repository #:nodoc:
|
31
|
+
@repository ||= instantiate_repository
|
32
|
+
end
|
33
|
+
|
34
|
+
# Read the content of the <tt>about.yml</tt>.
|
35
|
+
# New feature of Rails 2.1.x http:://dev.rubyonrails.org/changeset/9098
|
36
|
+
def about
|
37
|
+
@about ||= repository.about
|
38
|
+
end
|
39
|
+
|
40
|
+
# Return the plugin summary.
|
41
|
+
def summary
|
42
|
+
about['summary']
|
43
|
+
end
|
44
|
+
|
45
|
+
# Try to guess the plugin name.
|
46
|
+
def guess_name
|
47
|
+
name = File.basename(@url)
|
48
|
+
if name == 'trunk' || name.empty?
|
49
|
+
name = File.basename(File.dirname(@url))
|
50
|
+
end
|
51
|
+
name.gsub!(/\.git$/, '') if name =~ /\.git$/
|
52
|
+
name
|
53
|
+
end
|
54
|
+
|
55
|
+
# Serialize the plugin to Hash format.
|
56
|
+
def to_hash
|
57
|
+
{ self.guess_name =>
|
58
|
+
{ 'type' => repository.scm_type,
|
59
|
+
'summary' => self.summary } }
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
# List all installed plugins.
|
64
|
+
def list
|
65
|
+
AbstractRepository.list
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
# Instantiate the repository.
|
71
|
+
# Look at <tt>AbstractRepository#instantiate_repository</tt> documentation.
|
72
|
+
def instantiate_repository
|
73
|
+
AbstractRepository.instantiate_repository(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module Sashimi
|
2
|
+
class PluginNotFound < StandardError #:nodoc:
|
3
|
+
def initialize(plugin_name, message = nil)
|
4
|
+
@plugin_name = plugin_name
|
5
|
+
@message = message
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@message || @plugin_name + " isn't in the local repository."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class AbstractRepository
|
14
|
+
@@local_repository_sub_path = File.join('.rails', 'plugins')
|
15
|
+
@@cache_file = '.plugins'
|
16
|
+
attr_accessor :plugin
|
17
|
+
|
18
|
+
def initialize(plugin)
|
19
|
+
self.plugin = plugin
|
20
|
+
end
|
21
|
+
|
22
|
+
# Remove the repository
|
23
|
+
def uninstall
|
24
|
+
change_dir_to_local_repository
|
25
|
+
raise PluginNotFound.new(plugin.name) unless File.exists?(plugin.name)
|
26
|
+
FileUtils.rm_rf(plugin.name)
|
27
|
+
remove_from_cache
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add to a Rails app.
|
31
|
+
def add
|
32
|
+
puts plugin.name.titleize + "\n"
|
33
|
+
copy_plugin_to_rails_app
|
34
|
+
remove_hidden_folders
|
35
|
+
run_install_hook
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
def instantiate_repository(plugin)
|
40
|
+
unless plugin.name.nil?
|
41
|
+
instantiate_repository_by_cache(plugin)
|
42
|
+
else
|
43
|
+
instantiate_repository_by_url(plugin)
|
44
|
+
end.new(plugin)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return all installed plugin names
|
48
|
+
def list
|
49
|
+
cache_content.sort.collect do |plugin, contents|
|
50
|
+
"#{plugin}\t\t#{contents['summary']}"
|
51
|
+
end.join("\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
def local_repository_path #:nodoc:
|
55
|
+
@local_repository_path ||= File.join(find_home, @@local_repository_sub_path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def cache_file #:nodoc:
|
59
|
+
@@cache_file
|
60
|
+
end
|
61
|
+
|
62
|
+
# Return the path to the Rails app where the user launched sashimi command.
|
63
|
+
def path_to_rails_app
|
64
|
+
$rails_app
|
65
|
+
end
|
66
|
+
|
67
|
+
# Read the cache file and return the content as an <tt>Hash</tt>.
|
68
|
+
def cache_content
|
69
|
+
change_dir_to_local_repository
|
70
|
+
@@cache_content ||= (YAML::load_file(cache_file) || {}).to_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def instantiate_repository_by_url(plugin)
|
74
|
+
git_url?(plugin.url) ? GitRepository : SvnRepository
|
75
|
+
end
|
76
|
+
|
77
|
+
def instantiate_repository_by_cache(plugin)
|
78
|
+
cached_plugin = cache_content[plugin.name]
|
79
|
+
raise PluginNotFound.new(plugin.name) if cached_plugin.nil?
|
80
|
+
cached_plugin['type'] == 'git' ? GitRepository : SvnRepository
|
81
|
+
end
|
82
|
+
|
83
|
+
# Changes the current directory with the given one
|
84
|
+
def change_dir(dir)
|
85
|
+
FileUtils.cd(dir)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Change the current directory with local_repository_path
|
89
|
+
def change_dir_to_local_repository
|
90
|
+
change_dir(local_repository_path)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Rails app plugins dir
|
94
|
+
def plugins_dir
|
95
|
+
@@plugins_dir ||= File.join('vendor', 'plugins')
|
96
|
+
end
|
97
|
+
|
98
|
+
# Find the user home directory
|
99
|
+
def find_home
|
100
|
+
['HOME', 'USERPROFILE'].each do |homekey|
|
101
|
+
return ENV[homekey] if ENV[homekey]
|
102
|
+
end
|
103
|
+
if ENV['HOMEDRIVE'] && ENV['HOMEPATH']
|
104
|
+
return "#{ENV['HOMEDRIVE']}:#{ENV['HOMEPATH']}"
|
105
|
+
end
|
106
|
+
begin
|
107
|
+
File.expand_path("~")
|
108
|
+
rescue StandardError => ex
|
109
|
+
if File::ALT_SEPARATOR
|
110
|
+
"C:/"
|
111
|
+
else
|
112
|
+
"/"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Try to guess if it's a Git url.
|
118
|
+
def git_url?(url)
|
119
|
+
url =~ /^git:\/\// || url =~ /\.git$/
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Return the SCM type
|
124
|
+
#
|
125
|
+
# Subversion # => svn
|
126
|
+
# Git # => git
|
127
|
+
def scm_type
|
128
|
+
self.class.name.demodulize.gsub(/Repository$/, '').downcase
|
129
|
+
end
|
130
|
+
|
131
|
+
# Read the content of the <tt>about.yml</tt>.
|
132
|
+
# New feature of Rails 2.1.x http:://dev.rubyonrails.org/changeset/9098
|
133
|
+
def about
|
134
|
+
change_dir_to_plugin_path
|
135
|
+
return {} unless File.exists?('about.yml')
|
136
|
+
(YAML::load_file('about.yml') || {}).to_hash
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
# Proxy for <tt>AbstractRepository#change_dir</tt>
|
141
|
+
def change_dir(dir)
|
142
|
+
self.class.change_dir(dir)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Proxy for <tt>AbstractRepository#change_dir_to_local_repository</tt>
|
146
|
+
def change_dir_to_local_repository
|
147
|
+
self.class.change_dir_to_local_repository
|
148
|
+
end
|
149
|
+
|
150
|
+
# Change the current directory with the plugin one
|
151
|
+
def change_dir_to_plugin_path
|
152
|
+
change_dir(File.join(local_repository_path, plugin.name || plugin.guess_name))
|
153
|
+
end
|
154
|
+
|
155
|
+
# Proxy for <tt>AbstractRepository#local_repository_path</tt>
|
156
|
+
def local_repository_path
|
157
|
+
self.class.local_repository_path
|
158
|
+
end
|
159
|
+
|
160
|
+
# Proxy for <tt>AbstractRepository#cache_file</tt>
|
161
|
+
def cache_file
|
162
|
+
self.class.cache_file
|
163
|
+
end
|
164
|
+
|
165
|
+
# Proxy for <tt>AbstractRepository#cache_content</tt>
|
166
|
+
def cache_content
|
167
|
+
self.class.cache_content
|
168
|
+
end
|
169
|
+
|
170
|
+
# Proxy for <tt>AbstractRepository#plugins_dir</tt>
|
171
|
+
def plugins_dir
|
172
|
+
self.class.plugins_dir
|
173
|
+
end
|
174
|
+
|
175
|
+
# Proxy for <tt>AbstractRepository#path_to_rails_app</tt>
|
176
|
+
def path_to_rails_app
|
177
|
+
self.class.path_to_rails_app
|
178
|
+
end
|
179
|
+
|
180
|
+
# Prepare the plugin installation
|
181
|
+
def prepare_installation
|
182
|
+
FileUtils.mkdir_p(local_repository_path)
|
183
|
+
change_dir_to_local_repository
|
184
|
+
FileUtils.touch(cache_file)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Add a plugin into the cache
|
188
|
+
def add_to_cache(plugin)
|
189
|
+
write_to_cache cache_content.to_hash.merge!(plugin)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Remove a plugin from the cache
|
193
|
+
def remove_from_cache
|
194
|
+
cache_content.delete(plugin.name)
|
195
|
+
write_to_cache cache_content
|
196
|
+
end
|
197
|
+
|
198
|
+
# Write all the plugins into the cache
|
199
|
+
def write_to_cache(plugins)
|
200
|
+
change_dir_to_local_repository
|
201
|
+
FileUtils.mv(cache_file, "#{cache_file}-backup")
|
202
|
+
File.open(cache_file, 'w'){|f| f.write(plugins.to_yaml)}
|
203
|
+
FileUtils.rm("#{cache_file}-backup")
|
204
|
+
end
|
205
|
+
|
206
|
+
# Copy a plugin to a Rails app.
|
207
|
+
def copy_plugin_to_rails_app
|
208
|
+
change_dir(path_to_rails_app)
|
209
|
+
FileUtils.mkdir_p(plugins_dir)
|
210
|
+
FileUtils.cp_r(File.join(local_repository_path, plugin.name), File.join(plugins_dir, plugin.name))
|
211
|
+
end
|
212
|
+
|
213
|
+
# Remove SCM hidden folders.
|
214
|
+
def remove_hidden_folders
|
215
|
+
require 'find'
|
216
|
+
change_dir(File.join(path_to_rails_app, plugins_dir, plugin.name))
|
217
|
+
Find.find('./') do |path|
|
218
|
+
if File.basename(path) == '.'+scm_type
|
219
|
+
FileUtils.remove_dir(path, true)
|
220
|
+
Find.prune
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
# Run the plugin install hook.
|
226
|
+
def run_install_hook
|
227
|
+
install_hook_file = File.join(plugins_dir, plugin.name, 'install.rb')
|
228
|
+
load install_hook_file if File.exist? install_hook_file
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sashimi
|
2
|
+
class GitRepository < AbstractRepository
|
3
|
+
def install
|
4
|
+
prepare_installation
|
5
|
+
puts plugin.guess_name.titleize + "\n\n"
|
6
|
+
system("git clone #{plugin.url}")
|
7
|
+
add_to_cache(plugin.to_hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def update
|
11
|
+
puts plugin.name.titleize + "\n\n"
|
12
|
+
change_dir_to_plugin_path
|
13
|
+
system('git pull')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sashimi
|
2
|
+
class SvnRepository < AbstractRepository
|
3
|
+
def install
|
4
|
+
prepare_installation
|
5
|
+
puts plugin.guess_name.titleize + "\n\n"
|
6
|
+
system("svn co #{plugin.url} #{plugin.guess_name}")
|
7
|
+
add_to_cache(plugin.to_hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
def update
|
11
|
+
puts plugin.name.titleize + "\n\n"
|
12
|
+
change_dir_to_plugin_path
|
13
|
+
system("svn up")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|