sixcore 0.3.4 → 0.4.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/Rakefile CHANGED
@@ -13,7 +13,7 @@ require 'rake/testtask'
13
13
  spec = Gem::Specification.new do |s|
14
14
  s.name = 'sixcore'
15
15
  s.rubyforge_project = s.name
16
- s.version = '0.3.4'
16
+ s.version = '0.4.0'
17
17
  s.has_rdoc = true
18
18
  s.extra_rdoc_files = ['README', 'LICENSE']
19
19
  s.summary = 'Basic Function Library for other six projects'
@@ -0,0 +1,5 @@
1
+ --- !ruby/struct:SixCore::ConfigCore
2
+ info: true
3
+ debug: false
4
+ log: true
5
+ verbose: false
@@ -0,0 +1,2 @@
1
+ --- !ruby/struct:SixCore::ConfigNsis
2
+ program: C:/Program Files (x86)/NSIS/makensis.exe
@@ -0,0 +1,2 @@
1
+ --- !ruby/struct:SixCore::ConfigSvn
2
+ program: svn
data/lib/sixcore/ftp.rb CHANGED
@@ -7,14 +7,15 @@ module SixCore
7
7
  class Ftp
8
8
  attr :ftp
9
9
  COMPONENT = 'SixCore::Ftp'
10
+ @@log = SixCore.log
10
11
 
11
12
  require 'net/ftp'
12
13
  # host:: String, Hostname
13
14
  # user:: String, Username
14
15
  # pass:: String, Password
15
16
  def initialize(host, user = '', pass = '')
16
- SixCore::debugs('Initialize', COMPONENT)
17
- SixCore::debug "Creating connection to ftp://#{user}:#{pass}@#{host} ..."
17
+ @@log.debug SixCore::prep_msg 'Initialize', :component => COMPONENT
18
+ @@log.debug "Creating connection to ftp://#{user}:#{pass}@#{host} ..."
18
19
  @host = host
19
20
  @user = user
20
21
  @pass = pass
@@ -27,7 +28,7 @@ module SixCore
27
28
  # localpath:: String, Localpath
28
29
  # remotepath:: String, Remotepath
29
30
  def get(filename = '', localpath = '', remotepath = '')
30
- SixCore::debug "Downloading #{filename} from #{@host}#{remotepath} ..."
31
+ @@log.debug "Downloading #{filename} from #{@host}#{remotepath} ..."
31
32
  @ftp.getbinaryfile("#{remotepath}#{filename}", "#{localpath}#{filename}", 1024) unless filename == ''
32
33
  end
33
34
 
@@ -48,7 +49,7 @@ module SixCore
48
49
  def put(filename = '', localpath = '', remotepath = '', temp = false, staytemp = false)
49
50
  file = filename
50
51
  file = "#{file}_tmp" if temp
51
- SixCore::debug "Uploading #{filename} to #{@host}#{remotepath} ..."
52
+ @@log.debug "Uploading #{filename} to #{@host}#{remotepath} ..."
52
53
  @ftp.putbinaryfile("#{localpath}#{filename}", "#{remotepath}#{file}", 1024) unless filename == ''
53
54
  @ftp.rename("#{remotepath}#{file}", "#{remotepath}#{filename}") if temp && !staytemp
54
55
  end
data/lib/sixcore/nsis.rb CHANGED
@@ -3,24 +3,31 @@
3
3
  =end
4
4
  require 'sixcore'
5
5
  module SixCore
6
+ ConfigNsis = Struct.new(:program)
7
+
6
8
  # Core Class for the Nullsoft Scriptable Install System
7
9
  class Nsis
8
10
  attr_reader(:template, :output)
9
11
  COMPONENT = 'SixCore::nsis'
10
12
 
11
- require 'sixcore/config/nsis'
13
+ @@log = SixCore.log
14
+ @@config = SixCore::read_config('nsis', 'sixcore/config')
15
+ def config
16
+ @@config
17
+ end
18
+
12
19
  # template:: Name of template to use
13
20
  # output:: Name of output file to use
14
21
  def initialize(template, output)
15
22
  @template = template
16
23
  @output = output
17
- SixCore::debug('Initialize', COMPONENT, [template, output])
24
+ @@log.debug SixCore::prep_msg 'Initialize', :component => COMPONENT, :verbose => [template, output]
18
25
  end
19
26
 
20
27
  # Creates the NSIS Setup output file
21
28
  # replace:: Array, Per Entry: [Search, Replace]
22
29
  def create_output(replace = [])
23
- SixCore::debug('Build', COMPONENT, replace)
30
+ @@log.debug SixCore::prep_msg 'Build', :component => COMPONENT, :verbose => replace
24
31
 
25
32
  # Read NSIS template file
26
33
  nsis = File.open(@template) do |file|
@@ -28,26 +35,23 @@ module SixCore
28
35
  end
29
36
 
30
37
  # exchange regex for new strings
31
- SixCore::debug('Replacing regex...', COMPONENT, [@output, replace])
38
+ @@log.debug SixCore::prep_msg 'Replacing regex...', :component => COMPONENT, :verbose => [@output, replace]
32
39
  nsis = SixCore::gsub_ar(nsis, replace) unless replace.empty?
33
40
 
34
41
  # write new nsis file
35
- SixCore::debug('Creating new nsis file...', COMPONENT, @output)
36
- File.new(@output, 'w') do |f|
37
- f.write nsis
38
- end
42
+ @@log.debug SixCore::prep_msg 'Creating new nsis file...', :component => COMPONENT, :verbose => @output
43
+ File.open(@output, 'w') do |file| file.write nsis end
39
44
 
40
45
  # compile new nsis file
41
- SixCore::debug('Creating output exe...', COMPONENT)
42
- r = SixCore::proc_cmd("\"#{PROGRAM_NSIS}\" \"#{@output}\"")
43
- r.each do |l|
44
- # TODO: Regex?
45
- if l =~ /Error \- aborting creation process/
46
- raise 'Failed creating NSIS Installed'
46
+ @@log.debug SixCore::prep_msg 'Creating output exe...', :component => COMPONENT
47
+ result = SixCore::proc_cmd("\"#{@@config.program}\" \"#{@output}\"")
48
+ result.each do |line|
49
+ if line =~ /Error \- aborting creation process/
50
+ raise 'Failed creating NSIS Installer'
47
51
  end
48
52
  end
49
53
 
50
- return @output
54
+ @output
51
55
  end
52
56
  end
53
57
  end
data/lib/sixcore/svn.rb CHANGED
@@ -3,12 +3,26 @@
3
3
  =end
4
4
  require 'sixcore'
5
5
  module SixCore
6
+ ConfigSvn = Struct.new(:program)
7
+
6
8
  # Core module for Subversion
7
9
  class Svn
8
10
  attr_accessor(:repos, :user, :pass)
11
+
9
12
  COMPONENT = 'SixCore::Svn'
13
+ REGEX_LINE = /------------------------------------------------------------------------/
14
+ REGEX_INFO = /r(.*) \| (.*) \| (.*) \| (.*) /
15
+ REGEX_REVISION = /Revision\: (.*)/
16
+ REGEX_MOD = /(^A )|(^M )|(^D )/
17
+ REGEX_PBO = /(.*)\.pbo(.*)/
18
+ REGEX_FOLDER = /(.*)\\(.*)/
19
+
20
+ @@log = SixCore.log
21
+ @@config = SixCore::read_config('svn', 'sixcore/config')
22
+ def config
23
+ @@config
24
+ end
10
25
 
11
- require 'sixcore/config/svn'
12
26
  # repos:: String, Repository folder or URL
13
27
  # user:: String, Username
14
28
  # pass:: String, Password
@@ -21,12 +35,11 @@ module SixCore
21
35
  # Command Execution function
22
36
  # cmd:: Command to execute, excl repositor, username, password
23
37
  def cmd(cmd)
24
- SixCore::debug('Command', COMPONENT, cmd)
38
+ @@log.debug SixCore::prep_msg('Command', :component => COMPONENT, :verbose => cmd)
25
39
  cmd = "#{cmd} #{@repos}" unless @repos.empty?
26
40
  cmd = "#{cmd} --username #{@user}" unless @user.empty?
27
41
  cmd = "#{cmd} --password #{@pass}" unless @pass.empty?
28
- r = SixCore::proc_cmd("#{SVN_BIN} #{cmd}")
29
- return r
42
+ SixCore::proc_cmd("#{@@config.program} #{cmd}")
30
43
  end
31
44
 
32
45
  # Generates diff list between revisions
@@ -34,27 +47,23 @@ module SixCore
34
47
  # old:: String or Integer, start revision number
35
48
  # new:: String or Integer, end revision number
36
49
  def diff(old, new)
37
- r = cmd("diff -r #{old}:#{new} --summarize").split('\n')
38
- return r
50
+ cmd("diff -r #{old}:#{new} --summarize").split("\n")
39
51
  end
40
52
 
41
53
  # Fetches SVN info
42
54
  def info()
43
- r = cmd('info').split('\n')
44
- return r
55
+ cmd('info').split("\n")
45
56
  end
46
57
 
47
58
  # Fetches SVN List
48
59
  def list()
49
- r = cmd('list').split('/\n')
50
- return r
60
+ cmd('list').split("\n")
51
61
  end
52
62
 
53
63
  # Executes SVN Update
54
64
  # Returns Array of Strings
55
65
  def update()
56
- r = cmd('update').split('\n')
57
- return r
66
+ cmd('update').split("\n")
58
67
  end
59
68
 
60
69
  # Generates log between revisions
@@ -62,8 +71,7 @@ module SixCore
62
71
  # new:: String or Integer, end revision number
63
72
  # Returns Array of Strings (log)
64
73
  def log(old, new)
65
- r = cmd("log -r#{old}:#{new}").split('\n')
66
- return r
74
+ cmd("log -r#{old}:#{new}").split("\n")
67
75
  end
68
76
 
69
77
  # Generates array list of log entry information
@@ -76,8 +84,8 @@ module SixCore
76
84
  i = -1
77
85
  entry = []
78
86
  com = []
79
- ar.each do |l|
80
- if /------------------------------------------------------------------------/.match(l) != nil
87
+ ar.each do |line|
88
+ if line =~ REGEX_LINE
81
89
  unless i == -1
82
90
  entry << com
83
91
  log << entry
@@ -88,12 +96,9 @@ module SixCore
88
96
  else
89
97
  i += 1
90
98
  if i == 1
91
- m = /r(.*) \| (.*) \| (.*) \| (.*) line/.match(l)
92
- if m != nil
93
- entry << [m[1], m[2], m[3], m[4]]
94
- end
99
+ entry << [$1, $2, $3, $4] if line =~ REGEX_INFO
95
100
  elsif i > 2
96
- com << l unless l.size == 0
101
+ com << line unless line.empty?
97
102
  end
98
103
  end
99
104
  end
@@ -104,9 +109,7 @@ module SixCore
104
109
  # Returns revision number
105
110
  def read_rev()
106
111
  inf = info()
107
- inf.each do |line|
108
- return $1 if line[/Revision\: (.*)/]
109
- end
112
+ inf.each do |line| return $1 if line[REGEX_REVISION] end
110
113
  end
111
114
 
112
115
 
@@ -115,7 +118,7 @@ module SixCore
115
118
  # folders:: Boolean, include folders?
116
119
  # slash:: String, what type of file system / \ should be used
117
120
  # Returns Array, Per Entry format: [integer, formatted entry string]
118
- def parse_entry(entry, folders = true, slash = '\\')
121
+ def parse_entry(entry, folders = true, slash = '/')
119
122
  # TODO: slash!
120
123
  # substract everything after first \
121
124
  if folders
@@ -123,33 +126,34 @@ module SixCore
123
126
  else
124
127
  entrymod = entry
125
128
  end
126
-
129
+ id = -1
127
130
  case entrymod
128
- when /A /
129
- entrymod.gsub!(/A /, '')
130
- if folders and entry =~ /(.*)\\(.*)/
131
- # subfolder, so it's a change
132
- return [1, entrymod]
133
- else
134
- return [0, entrymod]
135
- end
136
- when /M /
137
- entrymod.gsub!(/M /, '')
138
- return [1, entrymod]
139
- when /D /
140
- entrymod.gsub!(/D /, '')
141
- if folders and entry =~ /(.*)\\(.*)/
142
- # subfolder, so it's a change
143
- if entry =~ /(.*)\.pbo(.*)/
144
- return [2, entrymod]
131
+ when REGEX_MOD
132
+ unless $1.nil?
133
+ if folders and entry =~ REGEX_FOLDER
134
+ # subfolder, so it's a change
135
+ id = 1
145
136
  else
146
- return [1, entrymod]
137
+ id = 0
138
+ end
139
+ end
140
+
141
+ unless $2.nil?
142
+ id = 1
143
+ end
144
+
145
+ unless $3.nil?
146
+ id = 2
147
+ unless entry =~ REGEX_PBO
148
+ if folders and entry =~ REGEX_FOLDER
149
+ # subfolder, so it's a change
150
+ id = 1
151
+ end
147
152
  end
148
- else
149
- return [2, entrymod]
150
153
  end
154
+ entrymod.gsub!(REGEX_MOD, '')
155
+ return [id, entrymod]
151
156
  end
152
- return [-1, nil]
153
157
  end
154
158
  end
155
159
  end
data/lib/sixcore.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  =begin
2
2
  6thSense.eu Core Module, by Sickboy (sb_at_6thSense.eu)
3
3
  =end
4
- require 'sixcore/config/sixcore'
5
-
4
+ require 'FileUtils'
6
5
  gem 'log4r'
7
6
  require 'log4r'
8
7
 
@@ -10,30 +9,49 @@ require 'log4r'
10
9
  module SixCore
11
10
  MAINDIR = Dir.pwd
12
11
  COMPONENT = 'SixCore'
12
+ TITLE = '6thSense.eu Core'
13
+ VERSION = '0.4.0'
14
+ ConfigCore = Struct.new(:info, :debug, :log, :verbose)
15
+
16
+ module_function
17
+ def read_config(config, path)
18
+ obj = nil
19
+ if FileTest.exist?("config/#{config}.yaml")
20
+ File.open("config/#{config}.yaml") { |yf| obj = YAML::load( yf ) }
21
+ else
22
+ File.open("#{File.dirname(__FILE__)}/#{path}/#{config}.yaml") { |yf| obj = YAML::load( yf ) }
23
+ end
24
+ obj
25
+ end
26
+ @@config = read_config('core', 'sixcore/config')
27
+
28
+ def config
29
+ @@config
30
+ end
31
+
13
32
  @@log = Log4r::Logger.new(COMPONENT)
33
+ format1 = Log4r::PatternFormatter.new(:pattern => "[%l] %d: %m", :date_pattern => '%H:%M:%S')
34
+ format2 = Log4r::PatternFormatter.new(:pattern => "[%l] %c %d: %m", :date_pattern => '%H:%M:%S')
14
35
 
15
36
  # Create Outputters
16
- if LOG
37
+ if @@config.log
17
38
  o_file = Log4r::FileOutputter.new 'sixcore-file',
18
39
  'level' => 0, # All
19
- :filename => "#{COMPONENT}.log"
40
+ :filename => "#{COMPONENT}.log",
41
+ 'formatter' => format2
20
42
  #:maxsize => 1024
21
43
  @@log.outputters << o_file
22
44
  end
23
45
 
24
46
  o_out = Log4r::StdoutOutputter.new 'sixcore-stdout',
25
- 'level' => 2 # no DEBUG
47
+ 'level' => 2, # no DEBUG
48
+ 'formatter' => format1
26
49
 
27
50
  o_err = Log4r::StderrOutputter.new 'sixcore-stderr',
28
- 'level' => 4 # Error and Up
51
+ 'level' => 4, # Error and Up
52
+ 'formatter' => format1
29
53
 
30
54
  @@log.outputters << o_out << o_err
31
-
32
- # @@log = File.new(LOGFILE, 'a')
33
- # @@log.sync = true
34
-
35
- module_function
36
-
37
55
  def log()
38
56
  @@log
39
57
  end
@@ -51,110 +69,67 @@ module SixCore
51
69
  def clean(str)
52
70
  str.chomp!
53
71
  str.strip!
54
- return str
72
+ str
55
73
  end
56
74
 
57
75
  # Prepares string for output to logger
58
76
  # str:: String, Input
59
- # component:: String, Component
60
- # verbose:: String, Verbose (Only displayed when VERBOSE is true)
61
- # type:: Integer, format types 0 or 1
62
- def prep_msg(str, component, verbose, type = 0)
63
- str = "#{component} - #{str}" unless component.empty?
64
- case type
65
- when 0
66
- str += ' - ' + verbose.to_s if VERBOSE and verbose != ''
67
- when 1
68
- str = "(#{Time.now().strftime('%H:%M:%S')}) #{str}"
69
- str += ' - ' + verbose.to_s if VERBOSE and verbose != ''
70
- str = "=== #{str} ==="
71
- end
72
- return str
73
- end
74
-
75
- # Outputs string to info logger
76
- # str:: String, Input
77
- # component:: String, Component
78
- # verbose:: String, Verbose (Only displayed when VERBOSE is true)
79
- def info(str, component = '', verbose = '')
77
+ # options:: Hash, :component, :verbose, :format
78
+ def prep_msg(str, options = {})
80
79
  unless str.empty?
81
- @@log.info prep_msg(str, component, verbose, 0)
82
- end
83
- end
84
-
85
- # Outputs string to info logger with extra formatting
86
- # str:: String, Input
87
- # component:: String, Component
88
- # verbose:: String, Verbose (Only displayed when VERBOSE is true)
89
- def infos(str, component = '', verbose = '')
90
- unless str.empty?
91
- puts
92
- @@log.info prep_msg(str, component, verbose, 1)
93
- end
94
- end
95
-
96
- # Outputs string to debug logger
97
- # str:: String, Input
98
- # component:: String, Component
99
- # verbose:: String, Verbose (Only displayed when VERBOSE is true)
100
- def debug(str, component = '', verbose = '')
101
- unless str.empty? || !DEBUG
102
- puts
103
- @@log.debug prep_msg(str, component, verbose, 0)
104
- end
105
- end
106
-
107
- # Outputs string to debug logger with extra formatting
108
- # str:: String, Input
109
- # component:: String, Component
110
- # verbose:: String, Verbose (Only displayed when VERBOSE is true)
111
- def debugs(str, component = '', verbose = '')
112
- unless str.empty? || !DEBUG
113
- puts
114
- @@log.debug prep_msg(str, component, verbose, 1)
80
+ str = "#{options[:component]} - #{str}" if options[:component]
81
+ case options[:format]
82
+ when 'title'
83
+ str += ' - ' + options[:verbose].to_s if options[:verbose] and @@config.verbose
84
+ str = "=== #{str} ==="
85
+ puts # FIXME: NASTY!
86
+ else
87
+ str += ' - ' + options[:verbose].to_s if options[:verbose] and @@config.verbose
88
+ end
115
89
  end
90
+ str
116
91
  end
117
92
 
118
93
  # Replaces all search strings with replace strings from replace array
119
94
  # string:: String, Input
120
95
  # replace:: Array, per entry: [Search, Replace]
121
96
  def gsub_ar(string, replace)
122
- replace.each do |r|
123
- string.gsub!(r[0], r[1])
124
- end
125
- return string
97
+ replace.each do |r| string.gsub!(r[0], r[1]) end
98
+ string
126
99
  end
127
100
 
128
101
  # Put quotes around string
129
102
  # Returns quoted string
130
103
  # str:: String, Input
131
104
  def quote(str)
132
- return "\"#{str}\""
105
+ "\"#{str}\""
133
106
  end
134
107
 
135
108
  # Evals command and logs to debug if enabled
136
109
  # cmd:: String, command to eval
137
110
  def eval_cmd(cmd)
138
- eval cmd unless DEBUG or cmd.empty?
139
- SixCore::debug('Eval Command', COMPONENT, cmd)
111
+ eval cmd unless @@config.debug or cmd.empty?
112
+ @@log.debug prep_msg('Eval Command', :component => COMPONENT, :verbose => cmd)
140
113
  end
141
114
 
142
115
  # Executes system command and logs to debug if enabled
143
116
  # cmd:: String, command to execute
144
117
  def proc_cmd(cmd)
145
- unless DEBUG or cmd.empty?
118
+ unless @@config.debug or cmd.empty?
146
119
  r = (%x[#{cmd}])
147
- SixCore::debug('Proc Command', COMPONENT, [cmd, r])
120
+ @@log.debug prep_msg('Proc Command', :component => COMPONENT, :verbose => [cmd, r])
148
121
  return r
149
122
  end
150
123
  end
151
124
 
125
+ # TODO: Find library or write Native Ruby 'robocopy' alike features
126
+
152
127
  # Uses Roboycopy to update folders from source to destination
153
128
  # source:: String, Source folder
154
129
  # destination:: String, Destination folder
155
130
  # extra:: Extra parameters to supply to Robocopy
156
131
  def fileupdate(source, destination, extra = '')
157
- debug('Updating Files...', COMPONENT, [source, destination, extra])
132
+ @@log.debug prep_msg('Updating Files...', :component => COMPONENT, :verbose => [source, destination, extra])
158
133
  proc_cmd("robocopy #{source} #{destination} /S /TIMFIX /ZB /R:5 /W:5 #{extra}")
159
134
  end
160
135
 
@@ -163,34 +138,8 @@ module SixCore
163
138
  # destination:: String, Destination folder
164
139
  # extra:: Extra parameters to supply to Robocopy
165
140
  def filemirror(source, destination, extra = '')
166
- debug('Mirroring Files...', COMPONENT, [source, destination, extra])
141
+ @@log.debug prep_msg('Mirroring Files...', :component => COMPONENT, :verbose => [source, destination, extra])
167
142
  proc_cmd("robocopy #{source} #{destination} /MIR /TIMFIX /ZB /R:5 /W:5 #{extra}")
168
143
  end
169
-
170
- # Copies files from source to destination
171
- # source:: String, Source folder
172
- # destination:: String, Destination folder
173
- def filecopy(source, destination)
174
- debug('Copying Files...', COMPONENT, [source, destination])
175
- proc_cmd("copy /y \"#{source}\" \"#{destination}\\\"")
176
- end
177
-
178
- # Moves files from source to destination
179
- # source:: String, Source folder
180
- # destination:: String, Destination folder
181
- def filemove(source, destination)
182
- debug('Moving Files...', COMPONENT, [source, destination])
183
- proc_cmd("move /y \"#{source}\" \"#{destination}\"")
184
- end
185
-
186
- # Deletes files from source
187
- # source:: String, Source folder
188
- def filedel(source)
189
- debug('Deleting Files...', COMPONENT, [source])
190
- proc_cmd("del /f /q #{source}")
191
- end
192
- end
193
-
194
- component = '6thSense.eu Core'
195
- version = '0.3.4'
196
- SixCore::debugs "#{component} #{version} loaded"
144
+ @@log.debug "#{TITLE} #{VERSION} loaded"
145
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sixcore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sickboy
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-30 00:00:00 +01:00
12
+ date: 2008-12-02 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -26,13 +26,13 @@ files:
26
26
  - LICENSE
27
27
  - README
28
28
  - Rakefile
29
- - lib/sixcore/config/nsis.rb
30
- - lib/sixcore/config/sixcore.rb
31
- - lib/sixcore/config/svn.rb
32
29
  - lib/sixcore/ftp.rb
33
30
  - lib/sixcore/nsis.rb
34
31
  - lib/sixcore/svn.rb
35
32
  - lib/sixcore.rb
33
+ - lib/sixcore/config/core.yaml
34
+ - lib/sixcore/config/nsis.yaml
35
+ - lib/sixcore/config/svn.yaml
36
36
  has_rdoc: true
37
37
  homepage: http://6thsense.eu
38
38
  post_install_message:
@@ -1 +0,0 @@
1
- PROGRAM_NSIS = 'C:\\Program Files (x86)\\NSIS\\makensis.exe'
@@ -1,5 +0,0 @@
1
- INFO = true
2
- DEBUG = false
3
- LOG = true
4
- VERBOSE = false
5
- CLEAN_LOG = true
@@ -1 +0,0 @@
1
- SVN_BIN = 'svn'