cheese 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.txt +0 -0
- data/History.txt +0 -0
- data/LICENSE +22 -0
- data/Manifest.txt +30 -0
- data/README.txt +132 -0
- data/Rakefile +54 -0
- data/TODO.txt +11 -0
- data/bin/cheese +118 -0
- data/data/templates/footer.inc +1 -0
- data/data/templates/header.inc +46 -0
- data/data/templates/mongrel.inc +7 -0
- data/data/templates/proxy.inc +3 -0
- data/data/templates/vhost.inc +84 -0
- data/lib/cheese-setup.rb +144 -0
- data/lib/cheese/version.rb +9 -0
- data/lib/controller.rb +152 -0
- data/lib/database/mysql.rb +50 -0
- data/lib/database/postgresql.rb +29 -0
- data/lib/process.rb +17 -0
- data/lib/scm/subversion.rb +83 -0
- data/lib/verbose.rb +37 -0
- data/lib/web/domain.rb +22 -0
- data/lib/web/mongrel.rb +30 -0
- data/lib/web/nginx.rb +223 -0
- data/lib/web/proxy.rb +25 -0
- data/lib/web/virtual_host.rb +24 -0
- data/setup.rb +1360 -0
- metadata +80 -0
data/lib/cheese-setup.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# cheese-setup.rb
|
3
|
+
#
|
4
|
+
# Configure cheese-tools defaults and misc information
|
5
|
+
# This is a simple run-once script which needs LOTS of refactoring and cleanup
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'highline/import'
|
10
|
+
require 'fileutils'
|
11
|
+
require 'yaml'
|
12
|
+
|
13
|
+
def draw_line(count=20)
|
14
|
+
@line = '-' * count
|
15
|
+
say "<%= color(@line, :horizontal_line) %>"
|
16
|
+
end
|
17
|
+
|
18
|
+
def draw_box
|
19
|
+
draw_line 50
|
20
|
+
yield
|
21
|
+
draw_line 50
|
22
|
+
end
|
23
|
+
|
24
|
+
CHEESE_CONF = "/etc/cheese/cheese.conf"
|
25
|
+
SUPPORTED_SCMS = {
|
26
|
+
:svn => { :name => 'Subversion', :binary => 'svnserve' } }
|
27
|
+
SUPPORTED_DBS = {
|
28
|
+
:psql => { :name => 'Postgresql', :binary => 'psql' },
|
29
|
+
:mysql => { :name => 'MySQL', :binary => 'mysql' } }
|
30
|
+
SILENCER = ">/dev/null 2>/dev/null"
|
31
|
+
begin
|
32
|
+
FileUtils.mkdir '/etc/cheese' unless File.exists? '/etc/cheese'
|
33
|
+
FileUtils.touch CHEESE_CONF
|
34
|
+
|
35
|
+
preferences = {}
|
36
|
+
|
37
|
+
# Create a color scheme, naming color patterns with symbol names.
|
38
|
+
ft = HighLine::ColorScheme.new do |cs|
|
39
|
+
cs[:headline] = [ :bold, :yellow ]
|
40
|
+
cs[:horizontal_line] = [ :bold, :white ]
|
41
|
+
cs[:important] = [ :bold, :red ]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Assign that color scheme to HighLine...
|
45
|
+
HighLine.color_scheme = ft
|
46
|
+
|
47
|
+
say "<%= color('Welcome to the cheese setup utility', :headline) %>"
|
48
|
+
draw_line 37
|
49
|
+
|
50
|
+
say "Answer each of the following questions and then you'll be"
|
51
|
+
say "ready to start using cheese:"
|
52
|
+
|
53
|
+
# SCM
|
54
|
+
choose do |menu|
|
55
|
+
SUPPORTED_SCMS.each do |scm, details|
|
56
|
+
menu.choice(scm, details[:name]) do |command, extras|
|
57
|
+
preferences[:scm] = { :name => details[:name], :binary => details[:binary]}
|
58
|
+
say "What would you like the default #{details[:name]} username to be?"
|
59
|
+
preferences[:scm_user] = ask("=> ", String)
|
60
|
+
say "and what password would you like?"
|
61
|
+
preferences[:scm_pass] = ask("=> ", String){|prompt| prompt.echo = "*" }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
menu.choice(:skip, "You don't want to use one") do |command, details|
|
65
|
+
preferences[:scm] = :skip
|
66
|
+
end
|
67
|
+
menu.choice(:quit, "Exit setup") { exit }
|
68
|
+
end
|
69
|
+
|
70
|
+
# Database
|
71
|
+
say "What database engine are you using?"
|
72
|
+
choose do |menu|
|
73
|
+
SUPPORTED_DBS.each do |db, details|
|
74
|
+
menu.choice(db, details[:name]) do |command, extras|
|
75
|
+
preferences[:database_type] = { :name => details[:name], :binary => details[:binary] }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
menu.choice(:skip, "You don't want to use one") do |command, details|
|
79
|
+
preferences[:database_type] = :skip
|
80
|
+
end
|
81
|
+
menu.choice(:quit, "Exit setup") { exit }
|
82
|
+
end
|
83
|
+
|
84
|
+
# Rails stack combination
|
85
|
+
say "What Ruby on Rails stack are you using?"
|
86
|
+
choose do |menu|
|
87
|
+
menu.choice(:nginx, "Nginx with Mongrel") do |command, details|
|
88
|
+
preferences[:stack] = :nginx
|
89
|
+
end
|
90
|
+
menu.choice(:skip, "You don't want to use one") do |command, details|
|
91
|
+
preferences[:scm] = :skip
|
92
|
+
end
|
93
|
+
menu.choice(:quit, "Exit setup") { exit }
|
94
|
+
end
|
95
|
+
|
96
|
+
draw_box do
|
97
|
+
say "<%= color('You need a normal account for safety reasons, running as', :bold) %>"
|
98
|
+
say "<%= color('root is dangerous, so we need to do that', :bold) %>"
|
99
|
+
end
|
100
|
+
|
101
|
+
user = ask("What username would you like for logging into the system?", String)
|
102
|
+
unless user.empty?
|
103
|
+
preferences[:user] = user
|
104
|
+
%x{ useradd -c "Cheesey User" -d /home/#{preferences[:user].chomp} --create-home #{preferences[:user].chomp} #{SILENCER} }
|
105
|
+
say "and what password would you like to use with that?"
|
106
|
+
%x{ passwd #{preferences[:user]} }
|
107
|
+
%x{ addgroup scm #{SILENCER} }
|
108
|
+
%x{ usermod -g scm #{preferences[:user]} }
|
109
|
+
else
|
110
|
+
say "Skipping user creation (I assume you must have done this already then)"
|
111
|
+
end
|
112
|
+
|
113
|
+
say "Saving and setting up those selected options"
|
114
|
+
|
115
|
+
scm = %x{ which #{ preferences[:scm][:binary] } }
|
116
|
+
xinetd_service = <<-EOF
|
117
|
+
service #{ preferences[:scm][:binary] }
|
118
|
+
{
|
119
|
+
socket_type = stream
|
120
|
+
protocol = tcp
|
121
|
+
user = scm
|
122
|
+
wait = no
|
123
|
+
disable = no
|
124
|
+
server = #{ scm.chomp }
|
125
|
+
server_args = -i --root=/var/src
|
126
|
+
port = 3690
|
127
|
+
}
|
128
|
+
EOF
|
129
|
+
File.open("/etc/xinetd.d/#{preferences[:scm][:binary]}", 'w+') do |file|
|
130
|
+
file.puts xinetd_service
|
131
|
+
end
|
132
|
+
%x{ /etc/init.d/xinetd restart #{SILENCER} }
|
133
|
+
|
134
|
+
File.open(CHEESE_CONF, "w+", 0640) {|f| YAML.dump(preferences, f)}
|
135
|
+
|
136
|
+
say "Done"
|
137
|
+
|
138
|
+
rescue Errno::EPERM
|
139
|
+
puts "This script must be run with root privileges"
|
140
|
+
exit
|
141
|
+
rescue Errno::EACCES
|
142
|
+
puts "This script must be run with root privileges"
|
143
|
+
exit
|
144
|
+
end
|
data/lib/controller.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# controller.rb
|
2
|
+
#
|
3
|
+
# Validate the options given and delegate jobs to the other classes
|
4
|
+
#
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'rubygems'
|
8
|
+
rescue LoadError
|
9
|
+
# no rubygems to load, so we fail silently
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'yaml'
|
13
|
+
require 'process'
|
14
|
+
require 'verbose'
|
15
|
+
require 'database/mysql'
|
16
|
+
require 'database/postgresql'
|
17
|
+
require 'scm/subversion'
|
18
|
+
require 'web/domain'
|
19
|
+
require 'web/mongrel'
|
20
|
+
require 'web/nginx'
|
21
|
+
require 'web/proxy'
|
22
|
+
require 'web/virtual_host'
|
23
|
+
|
24
|
+
module Cheese
|
25
|
+
class Controller
|
26
|
+
|
27
|
+
CHEESE_CONF = "/etc/cheese/cheese.conf"
|
28
|
+
NGINX_CONF = '/etc/nginx/nginx.conf'
|
29
|
+
|
30
|
+
def initialize(options={})
|
31
|
+
# Check cheese --setup has been run
|
32
|
+
unless File.exists?(CHEESE_CONF)
|
33
|
+
puts "Please run cheese --setup before using any cheese actions."
|
34
|
+
exit
|
35
|
+
end
|
36
|
+
# Need a better way of doing this, so it works in all files
|
37
|
+
Cheese::Verbose.dry_run = options.delete(:dry_run)
|
38
|
+
Cheese::Verbose.loud = options.delete(:verbose)
|
39
|
+
@preferences = YAML.load(File.open(CHEESE_CONF))
|
40
|
+
@options = options
|
41
|
+
run_actions
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Run all actions necessary
|
47
|
+
def run_actions
|
48
|
+
# List vhosts
|
49
|
+
if ( @options[:actions].include?(:web_server) || @options[:actions].include?(:list_vhosts))
|
50
|
+
@nginx = Cheese::Nginx::Config.new(NGINX_CONF)
|
51
|
+
end
|
52
|
+
|
53
|
+
if @options[:actions].include? :list_vhosts
|
54
|
+
Cheese::Verbose.log_task("listing vhosts in nginx.conf") do
|
55
|
+
begin
|
56
|
+
@nginx.domains.each_with_index {|domain, i| puts "#{i}. #{domain.vhost.domain} - #{domain.proxy.ports.size} threads" }
|
57
|
+
rescue Exception => e
|
58
|
+
puts "Error listing vhosts:"
|
59
|
+
puts e.message
|
60
|
+
puts "exiting"
|
61
|
+
exit
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Nginx
|
67
|
+
if @options[:actions].include? :web_server
|
68
|
+
begin
|
69
|
+
Cheese::Verbose.log_task("back up nginx.conf") do
|
70
|
+
FileUtils.cp(NGINX_CONF, NGINX_CONF + ".old") if File.exists?(NGINX_CONF)
|
71
|
+
end
|
72
|
+
rescue Errno::EPERM
|
73
|
+
puts "This script must be run with root privileges"
|
74
|
+
exit
|
75
|
+
rescue Errno::EACCES
|
76
|
+
puts "This script must be run with root privileges"
|
77
|
+
exit
|
78
|
+
end
|
79
|
+
|
80
|
+
case @options[:remove]
|
81
|
+
when false
|
82
|
+
Cheese::Verbose.log_task("create nginx vhost (#{@options[:name]})") do
|
83
|
+
@added_domain = @nginx.add @options
|
84
|
+
end
|
85
|
+
when true
|
86
|
+
Cheese::Verbose.log_task("remove nginx vhost (#{@options[:name]})") do
|
87
|
+
@removed_domain = @nginx.remove @options
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@nginx.save
|
92
|
+
@nginx.restart
|
93
|
+
end
|
94
|
+
|
95
|
+
# Subversion
|
96
|
+
if @options[:actions].include? :scm
|
97
|
+
if @options[:remove]
|
98
|
+
Cheese::Verbose.log_task("remove subversion repository (#{@options[:name]})") do
|
99
|
+
svn = Cheese::Subversion::Repository.remove @options[:name]
|
100
|
+
end
|
101
|
+
else
|
102
|
+
Cheese::Verbose.log_task("add subversion repository (#{@options[:name]})") do
|
103
|
+
svn = Cheese::Subversion::Repository.create @options[:name]
|
104
|
+
end
|
105
|
+
Cheese::Verbose.log_task("set the default permissions on the repository") do
|
106
|
+
user, pass = @preferences[:scm_user].chomp, @preferences[:scm_pass].chomp
|
107
|
+
Cheese::Subversion::Repository.set_permissions( :name => @options[:name],
|
108
|
+
:access => {:anon => :none, :auth => :write},
|
109
|
+
:users => {:user => user, :pass => pass})
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Mongrel cluster file
|
115
|
+
if @options[:actions].include? :app_server
|
116
|
+
if @options[:remove]
|
117
|
+
Cheese::Verbose.log_task("remove the mongrel_cluster file") do
|
118
|
+
Cheese::Mongrel.remove(@removed_domain)
|
119
|
+
end
|
120
|
+
else
|
121
|
+
Cheese::Verbose.log_task("create the mongrel_cluster file") do
|
122
|
+
Cheese::Mongrel.create(@added_domain.host, @added_domain.proxy.ports)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Database
|
128
|
+
if @options[:actions].include? :database
|
129
|
+
if @options[:remove]
|
130
|
+
Cheese::Verbose.log_task("drop a database") do
|
131
|
+
Cheese::Verbose.log_task(" requiring lib/#{@options[:database_type]}")
|
132
|
+
require "database/#{@options[:database_type]}"
|
133
|
+
Cheese::Verbose.log_task(" creating class #{@options[:database_type].to_s.capitalize}")
|
134
|
+
db_klass = Cheese.const_get(@options[:database_type].to_s.capitalize.intern)
|
135
|
+
Cheese::Verbose.log_task(" executing remove command on #{@options[:name]}")
|
136
|
+
db_klass.remove(@options[:name])
|
137
|
+
end
|
138
|
+
else
|
139
|
+
Cheese::Verbose.log_task("create a database") do
|
140
|
+
Cheese::Verbose.log_task(" requiring lib/#{@options[:database_type]}")
|
141
|
+
require "database/#{@options[:database_type]}"
|
142
|
+
Cheese::Verbose.log_task(" creating class #{@options[:database_type].to_s.capitalize}")
|
143
|
+
db_klass = Cheese.const_get(@options[:database_type].to_s.capitalize.intern)
|
144
|
+
Cheese::Verbose.log_task(" executing create command")
|
145
|
+
db_klass.create(@options[:name])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# mysql.rb
|
2
|
+
#
|
3
|
+
# Create and remove mysql databases
|
4
|
+
#
|
5
|
+
|
6
|
+
require 'highline/import'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
module Cheese
|
10
|
+
|
11
|
+
class Mysql
|
12
|
+
|
13
|
+
# create a user and new db
|
14
|
+
def self.create(name)
|
15
|
+
puts "What is the root password for MySQL?"
|
16
|
+
pass = ask("=> "){|prompt| prompt.echo = "*" }.chomp
|
17
|
+
while true
|
18
|
+
puts "What is the database password you want for #{name.gsub(".", "_")}?"
|
19
|
+
dbpass1 = ask("=> "){|prompt| prompt.echo = "*" }.chomp
|
20
|
+
puts "Confirm that"
|
21
|
+
dbpass2 = ask("=> "){|prompt| prompt.echo = "*" }.chomp
|
22
|
+
if dbpass1.chomp == dbpass2.chomp
|
23
|
+
break
|
24
|
+
else
|
25
|
+
puts "Those passwords didn't match, try again:"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
puts "adding db and user"
|
29
|
+
tmpfile = Tempfile.new("mysql-create")
|
30
|
+
tmpfile.puts "CREATE DATABASE #{name.gsub(".", "_")};"
|
31
|
+
tmpfile.puts "GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP ON *.* TO '#{name.gsub(".", "_")}'@'localhost' IDENTIFIED BY '#{dbpass1}';"
|
32
|
+
tmpfile.close
|
33
|
+
%x{ mysql -u root -p#{pass} mysql < #{tmpfile.path} }
|
34
|
+
end
|
35
|
+
|
36
|
+
# remove a user and new db
|
37
|
+
def self.remove(name)
|
38
|
+
puts "What is the root password for MySQL?"
|
39
|
+
pass = ask("=> "){|prompt| prompt.echo = "*" }
|
40
|
+
|
41
|
+
tmpfile = Tempfile.new("mysql-drop")
|
42
|
+
tmpfile.puts "DROP DATABASE #{name.gsub(".", "_")};"
|
43
|
+
tmpfile.puts "DROP USER '#{name.gsub(".", "_")}'@'localhost';"
|
44
|
+
tmpfile.close
|
45
|
+
%x{ mysql -u root -p#{pass} < #{tmpfile.path} }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# postgresql.rb
|
2
|
+
#
|
3
|
+
# Create and remove postgresql databases
|
4
|
+
#
|
5
|
+
|
6
|
+
module Cheese
|
7
|
+
|
8
|
+
class Postgresql
|
9
|
+
SILENCER = ">/dev/null 2>/dev/null"
|
10
|
+
|
11
|
+
# create a user and new db
|
12
|
+
def self.create(name)
|
13
|
+
while
|
14
|
+
puts "We need to set a database password for #{name.gsub(".", "_")}."
|
15
|
+
end
|
16
|
+
|
17
|
+
%x{ su -c "createuser -S -D -R #{name.gsub(".", "_")} -W" postgres }
|
18
|
+
%x{ su -c "createdb #{name.gsub(".", "_")}" postgres #{SILENCER} }
|
19
|
+
end
|
20
|
+
|
21
|
+
# remove a user and new db
|
22
|
+
def self.remove(name)
|
23
|
+
%x{ su -c "dropuser #{name.gsub(".", "_")}" postgres #{SILENCER} }
|
24
|
+
%x{ su -c "dropdb #{name.gsub(".", "_")}" postgres #{SILENCER} }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/process.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# process.rb
|
2
|
+
#
|
3
|
+
# Run a process as a different user
|
4
|
+
# Thanks to the "Ruby Cookbook" for this one
|
5
|
+
|
6
|
+
module Process
|
7
|
+
def as_uid(uid=0)
|
8
|
+
old_euid, old_uid = Process.euid, Process.uid
|
9
|
+
Process.euid, Process.uid = uid, uid
|
10
|
+
begin
|
11
|
+
yield
|
12
|
+
ensure
|
13
|
+
Process.euid, Process.uid = old_euid, old_uid
|
14
|
+
end
|
15
|
+
end
|
16
|
+
module_function(:as_uid)
|
17
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# subversion.rb
|
2
|
+
#
|
3
|
+
# Acts as a subversion repository
|
4
|
+
# This could be done with the svn ruby bindings, but it's simple
|
5
|
+
# stuff that for now will be fine using system
|
6
|
+
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
module Cheese
|
10
|
+
module Subversion
|
11
|
+
class Repository
|
12
|
+
DEFAULT_ACCESS = { :anon => :none, :auth => :write }
|
13
|
+
SILENCER = ">/dev/null 2>/dev/null"
|
14
|
+
def self.create(name)
|
15
|
+
# Create the repo
|
16
|
+
%x{ svnadmin create /var/src/#{name} #{SILENCER} }
|
17
|
+
%x{ chown svn:svn /var/src/#{name} #{SILENCER} }
|
18
|
+
%x{ chmod -R 774 /var/src/#{name} #{SILENCER} }
|
19
|
+
|
20
|
+
folder = self.create_tmp_structure
|
21
|
+
self.import(name, folder)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create the default file structure
|
25
|
+
def self.create_tmp_structure
|
26
|
+
FileUtils.mkdir_p( File.join(Dir.tmpdir, "/svn_structure/branches")) unless File.exists? File.join(Dir.tmpdir, "/svn_structure/branches")
|
27
|
+
FileUtils.mkdir( File.join(Dir.tmpdir, "/svn_structure/trunk")) unless File.exists? File.join(Dir.tmpdir, "/svn_structure/trunk")
|
28
|
+
FileUtils.mkdir( File.join(Dir.tmpdir, "/svn_structure/tags")) unless File.exists? File.join(Dir.tmpdir, "/svn_structure/tags")
|
29
|
+
File.join(Dir.tmpdir, "/svn_structure")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Set the permissions on a repository, defaults are anon-access: none and auth-access: write.
|
33
|
+
# These options can be changed with options
|
34
|
+
#
|
35
|
+
# ==== Options
|
36
|
+
# +options+
|
37
|
+
# +access+: A Hash containing :anon and :auth which can be set to either :none, :read or :write
|
38
|
+
# +users+: An Array or Hash containing user/pass combinations
|
39
|
+
# e.g. { :name => "Jamie", :password => "Chees3y" }
|
40
|
+
def self.set_permissions(options={})
|
41
|
+
access = options.delete(:access) || DEFAULT_ACCESS
|
42
|
+
name = options.delete(:name)
|
43
|
+
File.open("/var/src/#{name}/conf/svnserve.conf", "w+") do |file|
|
44
|
+
file.puts "# Generated on #{Time.now.to_s}"
|
45
|
+
file.puts "[general]"
|
46
|
+
file.puts "anon-access = #{access[:anon].to_s}"
|
47
|
+
file.puts "auth-access = #{access[:auth].to_s}"
|
48
|
+
file.puts "password-db = passwd"
|
49
|
+
end
|
50
|
+
File.open("/var/src/#{name}/conf/passwd", "w+") do |file|
|
51
|
+
file.puts "[users]"
|
52
|
+
if options[:users].is_a?Array
|
53
|
+
options[:users].each do |user, pass|
|
54
|
+
file.puts "#{user} = #{pass}"
|
55
|
+
end
|
56
|
+
elsif options[:users].is_a?Hash
|
57
|
+
file.puts "#{options[:users][:user]} = #{options[:users][:pass]}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.remove(name)
|
63
|
+
FileUtils.rm_rf("/var/src/#{name}")
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.import(name, files=[], extra_path="")
|
67
|
+
files.each do |file|
|
68
|
+
%x{ svn import #{file} file:///var/src/#{name}#{extra_path} -m "import of #{file}" }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.remove_file(name, files=[])
|
73
|
+
if files.is_a?Array
|
74
|
+
files.each do |file|
|
75
|
+
%x{ svn delete #{file} file:///var/src/#{name} -m "deleted #{file}" #{SILENCER} } if File.exists? file
|
76
|
+
end
|
77
|
+
else
|
78
|
+
%x{ svn delete #{files} file:///var/src/#{name} -m "deleted #{files} #{SILENCER}" } if File.exists? files
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|