skadategems-dev 0.0.9

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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +12 -0
  4. data/Gemfile +13 -0
  5. data/Guardfile +8 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +74 -0
  8. data/Rakefile +6 -0
  9. data/bin/skadate +9 -0
  10. data/bin/skadategems-dev +18 -0
  11. data/integration/README.md +97 -0
  12. data/integration/cli/skadate_init_spec.rb +86 -0
  13. data/integration/cli/skadate_spec.rb +50 -0
  14. data/integration/cli/spec_helper.rb +23 -0
  15. data/integration/lib/remote/download_file_spec.rb +136 -0
  16. data/integration/spec_helper.rb +101 -0
  17. data/lib/skadategems/dev/bundle.rb +115 -0
  18. data/lib/skadategems/dev/cli/remote.rb +364 -0
  19. data/lib/skadategems/dev/cli/skadate.rb +184 -0
  20. data/lib/skadategems/dev/remote.rb +170 -0
  21. data/lib/skadategems/dev/remote/clone_logger.rb +118 -0
  22. data/lib/skadategems/dev/remote/configs.rb +97 -0
  23. data/lib/skadategems/dev/remote/directory.rb +88 -0
  24. data/lib/skadategems/dev/remote/file.rb +157 -0
  25. data/lib/skadategems/dev/remote/includes/mysql_connect.php +8 -0
  26. data/lib/skadategems/dev/skadate.rb +30 -0
  27. data/lib/skadategems/dev/software_version.rb +66 -0
  28. data/lib/skadategems/dev/source_controller.rb +101 -0
  29. data/lib/skadategems/dev/version.rb +5 -0
  30. data/skadategems-dev.gemspec +33 -0
  31. data/spec/skadategems/dev/bundle_spec.rb +268 -0
  32. data/spec/skadategems/dev/cli/remote_spec.rb +623 -0
  33. data/spec/skadategems/dev/cli/skadate_spec.rb +182 -0
  34. data/spec/skadategems/dev/remote/clone_logger_spec.rb +324 -0
  35. data/spec/skadategems/dev/remote/directory_spec.rb +117 -0
  36. data/spec/skadategems/dev/remote/file_spec.rb +74 -0
  37. data/spec/skadategems/dev/remote_spec.rb +95 -0
  38. data/spec/skadategems/dev/skadate_spec.rb +62 -0
  39. data/spec/skadategems/dev/software_version_spec.rb +92 -0
  40. data/spec/skadategems/dev/source_controller_spec.rb +243 -0
  41. data/spec/spec_helper.rb +32 -0
  42. metadata +153 -0
@@ -0,0 +1,101 @@
1
+ require 'skadategems/dev/software_version'
2
+
3
+ module SkadateGems
4
+ module Dev
5
+
6
+ # Skadate software source controller
7
+ class SourceController
8
+
9
+ # @return [String] source root directory
10
+ attr_reader :root
11
+
12
+ # @param root_dir [String] source root directory
13
+ def initialize(root_dir)
14
+ @root = root_dir
15
+ end
16
+
17
+ # Get full path to a file from the current source model.
18
+ # @param relative_path [String] relative path to a file
19
+ # @return [String] absolute path to a file
20
+ def filename(relative_path)
21
+ File.join(@root, relative_path)
22
+ end
23
+
24
+ # @return [String] full path to a `internals/Header.inc.php` file
25
+ def header_inc_php
26
+ filename 'internals/Header.inc.php'
27
+ end
28
+
29
+ # Silently tries to get software version object.
30
+ # @return [SoftwareVersion] or nil in case of file reading or parsing error
31
+ def version
32
+ return @version if @version
33
+
34
+ begin
35
+ string_def = parse_version_definition
36
+ if SoftwareVersion::MAP.key?(string_def)
37
+ @version = SoftwareVersion::MAP[string_def]
38
+ else
39
+ @version = SoftwareVersion.new(string_def)
40
+ end
41
+ rescue Errno::ENOENT, ParseError
42
+ nil
43
+ end
44
+ end
45
+
46
+ # @return [SoftwareVersion] software version object
47
+ # @raise [IOError] if `internals/Header.inc.php` can not be found
48
+ # @raise [SoftwareVersion::IncompatibilityError]
49
+ # if detected version is not compatible with current version of `skadategems-dev`
50
+ def version!
51
+ if @version.nil?
52
+ string_def = parse_version_definition
53
+
54
+ if SoftwareVersion::MAP.key?(string_def)
55
+ @version = SoftwareVersion::MAP[string_def]
56
+ else
57
+ raise SoftwareVersion::CompatibilityError
58
+ end
59
+ end
60
+
61
+ @version
62
+ end
63
+
64
+ # Search and parse for a version definition within the `#header_inc_php` file.
65
+ # @raise [SourceController::ParseError] if the version definition can not be parsed
66
+ # @private use #version or #version! to gather a software version
67
+ def parse_version_definition
68
+ File.open(header_inc_php) do |file|
69
+ /define\(\s?(['"])PACKAGE_VERSION\1\s?,\s?(['"])(\d{1,2}.\d{1,2}.\d{4})\2\s?\)\s?;/.match(file.read)
70
+ end
71
+
72
+ $3 or raise ParseError
73
+ end
74
+
75
+ # @return [String] full path to a `internal_c/` directory
76
+ def internal_c
77
+ filename (version!.build < 2960 ? '$internal_c' : 'internal_c')
78
+ end
79
+
80
+ # @return [String] full path to a `external_c/` directory
81
+ def external_c
82
+ filename (version!.build < 2960 ? '$external_c' : 'external_c')
83
+ end
84
+
85
+ # @return [String] full path to a `userfiles/` directory
86
+ def userfiles
87
+ filename (version!.build < 2960 ? '$userfiles' : 'userfiles')
88
+ end
89
+
90
+ # @return [String] full path to a `internals/config.php` file
91
+ def config_php
92
+ filename ("internals/#{(version!.build < 2960 ? '$config.php' : 'config.php')}")
93
+ end
94
+
95
+ # Raised in case of source file parse error.
96
+ # @see SourceController#version!
97
+ class ParseError < StandardError; end
98
+ end
99
+
100
+ end
101
+ end
@@ -0,0 +1,5 @@
1
+ module SkadateGems
2
+ module Dev
3
+ VERSION = '0.0.9'
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'skadategems/dev/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'skadategems-dev'
8
+ spec.version = SkadateGems::Dev::VERSION
9
+ spec.summary = 'Skadate Development Toolkit'
10
+ spec.homepage = 'https://github.com/skadategems/skadategems-dev'
11
+
12
+ spec.description = <<-EOT
13
+ Command line tool for Skadate Software developers
14
+ EOT
15
+
16
+ spec.author = 'Dan Kerimdzhanov'
17
+ spec.email = 'kerimdzhanov@gmail.com'
18
+ spec.license = 'MIT'
19
+
20
+ spec.files = `git ls-files`.split($/)
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^spec/})
23
+ spec.require_paths = %w[lib]
24
+
25
+ spec.platform = Gem::Platform::RUBY
26
+ spec.required_ruby_version = '>= 2.0.0'
27
+
28
+ spec.add_dependency 'thor', '~> 0.18.1'
29
+ spec.add_dependency 'execphp', '~> 0.1.0'
30
+ spec.add_dependency 'ruby-progressbar', '~> 1.4.2'
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.5.3'
33
+ end
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+ require 'skadategems/dev/skadate'
3
+ require 'skadategems/dev/bundle'
4
+
5
+ module SkadateGems
6
+ module Dev
7
+
8
+ describe Bundle do
9
+ let(:root_dir) { '/path/to/skadate' }
10
+
11
+ let(:source) do
12
+ double(SourceController, root: root_dir,
13
+ internal_c: File.join(root_dir, 'internal_c'),
14
+ external_c: File.join(root_dir, 'external_c'),
15
+ userfiles: File.join(root_dir, 'userfiles'),
16
+ filename: File.join(root_dir, 'layout/themes/'))
17
+ end
18
+
19
+ let(:skadate) { double(Skadate, source: source) }
20
+
21
+ let(:bundle) { Bundle.new(skadate) }
22
+
23
+ describe '#should_include?' do
24
+
25
+ %w[ admin
26
+ cron/heavy.php
27
+ internals/API/Component.class.php
28
+ layout/themes/fb/img/logo.gif
29
+ ].each do |file|
30
+ it "allows `#{file}`" do
31
+ filename = File.join(root_dir, file)
32
+ expect(bundle.should_include?(filename)).to be_true
33
+ end
34
+ end
35
+
36
+ %w[ internal_c
37
+ internal_c/lang
38
+ external_c
39
+ external_c/%123D/%456%K.php
40
+ userfiles
41
+ userfiles/1234_5678/1234_5678.jpg
42
+ previous.tar.gz
43
+ archived.zip
44
+ vi-cache.swp
45
+ tmp-file.txt~
46
+ Thumbs.db
47
+ desktop.ini
48
+ ].each do |file|
49
+ it "denies `#{file}`" do
50
+ filename = File.join(root_dir, file)
51
+ expect(bundle.should_include?(filename)).to be_false
52
+ end
53
+ end
54
+
55
+ context 'when `bundle#layout_theme` is set to "dp"' do
56
+ before(:each) { bundle.layout_theme = 'dp' }
57
+
58
+ %w[ layout/themes
59
+ layout/themes/dp
60
+ layout/themes/dp/components
61
+ layout/themes/dp/img/logo.gif
62
+ ].each do |file|
63
+ it "allows `#{file}`" do
64
+ filename = File.join(root_dir, file)
65
+ expect(bundle.should_include?(filename)).to be_true
66
+ end
67
+ end
68
+
69
+ %w[ layout/themes/bn
70
+ layout/themes/ct/components
71
+ layout/themes/fb/img/logo.gif
72
+ ].each do |file|
73
+ it "denies `#{file}`" do
74
+ filename = File.join(root_dir, file)
75
+ expect(bundle.should_include?(filename)).to be_false
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+
82
+ describe '#tar' do
83
+ let(:tar_io) do
84
+ tar_io = double(Gem::Package::TarWriter)
85
+ allow(tar_io).to receive(:mkdir)
86
+ tar_io
87
+ end
88
+
89
+ let(:tar_file) do
90
+ tar_file = double('tar_file')
91
+
92
+ tar_file
93
+ end
94
+
95
+ before(:each) do
96
+ allow(Gem::Package::TarWriter).to receive(:new) do |string_io, &block|
97
+ block.call(tar_io)
98
+ end
99
+
100
+ allow(Dir).to receive(:[]).and_return []
101
+
102
+ allow(File).to receive(:exists?).and_return false
103
+ end
104
+
105
+ it 'checks for root `.htaccess` existence' do
106
+ expect(File).to receive(:exists?)
107
+ .with('/path/to/skadate/.htaccess')
108
+ bundle.tar
109
+ end
110
+
111
+ context 'when root `.htaccess` exists' do
112
+ before(:each) do
113
+ allow(File).to receive(:exists?)
114
+ .with('/path/to/skadate/.htaccess')
115
+ .and_return true
116
+
117
+ allow(tar_io).to receive(:add_file)
118
+ .with('.htaccess', 0644) do |&block|
119
+ block.call(tar_file)
120
+ end
121
+ end
122
+
123
+ it 'adds it with attributes "-rw-r--r--"' do
124
+ expect(tar_io).to receive(:add_file)
125
+ .with('.htaccess', 0644) {}
126
+ bundle.tar
127
+ end
128
+
129
+ it 'includes its contents' do
130
+ expect(File).to receive(:open)
131
+ .with('/path/to/skadate/.htaccess', 'rb') do |&block|
132
+ block.call(double('IO', read: 'htaccess contents'))
133
+ end
134
+
135
+ expect(tar_file).to receive(:write)
136
+ .with('htaccess contents')
137
+
138
+ bundle.tar
139
+ end
140
+ end
141
+
142
+ it 'globs :root_dir recursively' do
143
+ expect(Dir).to receive(:[])
144
+ .with('/path/to/skadate/**/*')
145
+ .and_return []
146
+
147
+ bundle.tar
148
+ end
149
+
150
+ context 'when meets a directory' do
151
+ before(:each) do
152
+ allow(Dir).to receive(:[])
153
+ .and_return %w[/path/to/skadate/internals]
154
+
155
+ allow(File).to receive(:directory?).and_return true
156
+ end
157
+
158
+ it 'includes it with attributes "drwxr-xr-x"' do
159
+ expect(tar_io).to receive(:mkdir).with('internals', 0755)
160
+ bundle.tar
161
+ end
162
+
163
+ it 'checks whether the directory contains `.htaccess`' do
164
+ expect(File).to receive(:exists?)
165
+ .with('/path/to/skadate/internals/.htaccess')
166
+
167
+ bundle.tar
168
+ end
169
+
170
+ context 'if directory contains `.htaccess`' do
171
+ before(:each) do
172
+ allow(File).to receive(:exists?)
173
+ .with('/path/to/skadate/internals/.htaccess')
174
+ .and_return true
175
+
176
+ allow(tar_io).to receive(:add_file)
177
+ .with('internals/.htaccess', 0644) do |&block|
178
+ block.call(tar_file)
179
+ end
180
+ end
181
+
182
+ it 'adds it with attributes "-rw-r--r--"' do
183
+ expect(tar_io).to receive(:add_file)
184
+ .with('internals/.htaccess', 0644) {}
185
+ bundle.tar
186
+ end
187
+
188
+ it 'includes its contents' do
189
+ expect(File).to receive(:open)
190
+ .with('/path/to/skadate/internals/.htaccess', 'rb') do |&block|
191
+ block.call(double('IO', read: 'htaccess contents'))
192
+ end
193
+
194
+ expect(tar_file).to receive(:write)
195
+ .with('htaccess contents')
196
+
197
+ bundle.tar
198
+ end
199
+ end
200
+ end
201
+
202
+ context 'when meets a file' do
203
+ before(:each) do
204
+ allow(Dir).to receive(:[])
205
+ .and_return %w[/path/to/skadate/member/index.php]
206
+
207
+ allow(File).to receive(:directory?).and_return false
208
+
209
+ allow(tar_io).to receive(:add_file) do |&block|
210
+ block.call(tar_file)
211
+ end
212
+ end
213
+
214
+ it 'adds it with mode "-rw-r--r--"' do
215
+ expect(tar_io).to receive(:add_file)
216
+ .with('member/index.php', 0644) {}
217
+ bundle.tar
218
+ end
219
+
220
+ it 'includes its contents' do
221
+ expect(File).to receive(:open)
222
+ .with('/path/to/skadate/member/index.php', 'rb') do |&block|
223
+ block.call(double('IO', read: 'file contents'))
224
+ end
225
+
226
+ expect(tar_file).to receive(:write)
227
+ .with('file contents')
228
+
229
+ bundle.tar
230
+ end
231
+ end
232
+
233
+ context "when meets a file that shouldn't be included" do
234
+ before(:each) do
235
+ expect(Dir).to receive(:[])
236
+ .and_return ['/path/to/skadate/internal_c/forms']
237
+ end
238
+
239
+ it 'skips the file' do
240
+ expect(File).to_not receive(:directory?)
241
+ bundle.tar
242
+ end
243
+ end
244
+
245
+ %w[internal_c internal_c/components internal_c/lang external_c userfiles].each do |dir|
246
+ it "includes empty `#{dir}/` with mode 0777" do
247
+ expect(tar_io).to receive(:mkdir).with(dir, 0777)
248
+ bundle.tar
249
+ end
250
+ end
251
+
252
+ it 'returns a `StringIO`' do
253
+ expect(Dir).to receive(:[]).and_return []
254
+ expect(bundle.tar).to be_a StringIO
255
+ end
256
+
257
+ it 'caches the resulting object' do
258
+ expect(Dir).to receive(:[]).and_return []
259
+ expect(bundle.tar).to equal bundle.tar
260
+ end
261
+ end
262
+
263
+ describe '#gzip' do
264
+ end
265
+ end
266
+
267
+ end
268
+ end
@@ -0,0 +1,623 @@
1
+ require 'spec_helper'
2
+ require 'skadategems/dev/cli/skadate'
3
+
4
+ module SkadateGems::Dev
5
+ module CLI
6
+
7
+ describe Remote do
8
+ def lib; SkadateGems::Dev end
9
+
10
+ let(:skadate) { lib::Skadate.new('/path/to/skadate') }
11
+
12
+ let(:accessor) do
13
+ double ExecPHP::RemoteServer,
14
+ execphp_uri: 'http://localhost/exec.php',
15
+ exec: nil
16
+ end
17
+
18
+ let(:remote) do
19
+ double lib::Remote,
20
+ accessor: accessor,
21
+ exec: nil
22
+ end
23
+
24
+ before(:each) do
25
+ allow(lib::Skadate)
26
+ .to receive(:new)
27
+ .and_return(skadate)
28
+
29
+ allow(skadate)
30
+ .to receive(:remote)
31
+ .and_return(remote)
32
+ end
33
+
34
+ describe '$> skadate remote ping' do
35
+ def ping!
36
+ @stdout = capture(:stdout) do
37
+ Skadate.start %w[remote ping]
38
+ end
39
+ end
40
+
41
+ it 'prints out a requesting url' do
42
+ ping!
43
+
44
+ expect(@stdout).to include "=> http://localhost/exec.php\n"
45
+ end
46
+
47
+ it 'sends the `echo` request to a remote server' do
48
+ expect(accessor).to receive(:exec) do |batch, &block|
49
+ expect(batch.to_s).to eq "echo \"pong!\";\n"
50
+ end
51
+
52
+ ping!
53
+ end
54
+
55
+ context 'when a response is received' do
56
+ let(:response) do
57
+ double 'http response', :code => 403,
58
+ :message => 'Found',
59
+ :body => ''
60
+ end
61
+
62
+ before(:each) do
63
+ allow(accessor).to receive(:exec) do |batch, &block|
64
+ block.call(response)
65
+ end
66
+ end
67
+
68
+ it 'prints out it‘s status code and message' do
69
+ ping!
70
+ expect(@stdout).to include "#> 403 [Found]\n"
71
+ end
72
+
73
+ context 'when a response body is empty' do
74
+ it 'prints out the "empty response body" error' do
75
+ ping!
76
+ expect(@stdout).to include "Error: empty response body\n"
77
+ end
78
+ end
79
+
80
+ context 'when a response body is unexpected' do
81
+ let(:response) do
82
+ double 'http response', :code => '200',
83
+ :message => 'OK',
84
+ :body => 'Oops...'
85
+ end
86
+
87
+ it 'prints out the "wrong response body" error including a response body' do
88
+ ping!
89
+
90
+ expect(@stdout).to include <<-STDOUT
91
+ Error: wrong response body:
92
+ "Oops..."
93
+ STDOUT
94
+ end
95
+
96
+ context 'if a response body is longer than 1000' do
97
+ let(:response) do
98
+ double 'http response', :code => '200',
99
+ :message => 'OK',
100
+ :body => 'a' * 1001
101
+ end
102
+
103
+ it 'truncates a response body length' do
104
+ ping!
105
+
106
+ expect(@stdout).to include <<-STDOUT
107
+ Error: wrong response body:
108
+ #{'a' * 985} ... (continued)
109
+ STDOUT
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'when a server responds with "pong!"' do
115
+ let(:response) do
116
+ double 'http response', :code => '200',
117
+ :message => 'OK',
118
+ :body => 'pong!'
119
+ end
120
+
121
+ it 'prints out ">> pong!"' do
122
+ ping!
123
+ expect(@stdout).to include ">> pong!\n"
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ describe '$> skadate remote exec FILENAME' do
131
+ def exec!
132
+ @stdout = capture(:stdout) do
133
+ Skadate.start %w[remote exec remote-script.php]
134
+ end
135
+ end
136
+
137
+ let(:response) do
138
+ double 'http response', :code => '200',
139
+ :message => 'OK',
140
+ :body => 'Yay!'
141
+ end
142
+
143
+ it 'puts a given php file to remote#exec as a batch script' do
144
+ batch = double(ExecPHP::ScriptBatch)
145
+
146
+ expect(remote).to receive(:exec)
147
+ .and_yield(batch)
148
+ .and_return(response)
149
+
150
+ expect(batch).to receive(:include_file)
151
+ .with('remote-script.php')
152
+
153
+ exec!
154
+ end
155
+
156
+ it 'prints out a response#body' do
157
+ expect(remote).to receive(:exec)
158
+ .and_return(response)
159
+
160
+ exec!
161
+
162
+ expect(@stdout).to eq "Yay!\n"
163
+ end
164
+ end
165
+
166
+ describe '$> skadate remote clone' do
167
+ def clone!(options)
168
+ @stdout = capture(:stdout) do
169
+ Skadate.start %w[remote clone].concat(options)
170
+ end
171
+ end
172
+
173
+ def directory(options = {})
174
+ double "remote dir `#{options[:path]}`", {
175
+ directory?: true,
176
+ list: []
177
+ }.merge(options)
178
+ end
179
+
180
+ def file(options = {})
181
+ size = options[:size] || 0
182
+
183
+ file = double "remote file `#{options[:path]}`", {
184
+ directory?: false,
185
+ path: options[:path],
186
+ size: size,
187
+ friendly_size: "#{size} bytes",
188
+ save_as: nil
189
+ }
190
+
191
+ allow(file).to receive(:basename) do
192
+ File.basename(options[:path])
193
+ end
194
+
195
+ allow(file).to receive(:extname) do
196
+ File.extname(options[:path])
197
+ end
198
+
199
+ file
200
+ end
201
+
202
+ let(:logger_mock) { double lib::Remote::CloneLogger }
203
+
204
+ before(:each) do
205
+ allow(::File)
206
+ .to receive(:exists?)
207
+ .with('/path/to/skadate/.dev/log')
208
+ .and_return(true)
209
+
210
+ allow(lib::Remote::CloneLogger)
211
+ .to receive(:start)
212
+ .and_yield(logger_mock)
213
+
214
+ allow(logger_mock)
215
+ .to receive(:puts)
216
+
217
+ allow(logger_mock)
218
+ .to receive(:entry)
219
+ .and_yield
220
+
221
+ @logger_padding = 0
222
+ allow(logger_mock).to receive(:padding) { @logger_padding }
223
+ allow(logger_mock).to receive(:padding=) { |val| @logger_padding = val }
224
+
225
+ allow(logger_mock).to receive(:mute?).and_return(false)
226
+ end
227
+
228
+ describe 'without arguments' do
229
+ it 'prints out the error message' do
230
+ clone! []
231
+ expect(@stdout).to include "Error: `remote clone` options are required\n"
232
+ end
233
+
234
+ it 'prints out the usage help' do
235
+ clone! []
236
+ expect(@stdout).to include "Usage:\n"
237
+ expect(@stdout).to include "Options:\n"
238
+ end
239
+ end
240
+
241
+ context '#logger.start' do
242
+ it 'mkdir -p `.dev/log` if not exists' do
243
+ expect(::File)
244
+ .to receive(:exists?)
245
+ .with('/path/to/skadate/.dev/log')
246
+ .and_return(false)
247
+
248
+ expect(FileUtils)
249
+ .to receive(:mkdir_p)
250
+ .with('/path/to/skadate/.dev/log')
251
+
252
+ allow(lib::Remote::CloneLogger)
253
+ .to receive(:start) # skip block
254
+
255
+ clone! %w[--database]
256
+ end
257
+
258
+ it 'calls logger.start("/path/to/skadate/.dev/log/remote-clone[$timestamp].log")' do
259
+ expect(lib::Remote::CloneLogger).to receive(:start) do |log_filename, &_|
260
+ expect(log_filename).to match %r[/path/to/skadate/\.dev/log/remote-clone\[\d+\]\.log]
261
+ end
262
+
263
+ clone! %w[--database]
264
+ end
265
+ end
266
+
267
+ describe '--sources' do
268
+ def clone_sources!
269
+ clone! %w[--sources]
270
+ end
271
+
272
+ let(:root_dir) { directory path: '/' }
273
+ let(:admin_dir) { directory path: '/admin' }
274
+ let(:templates_dir) { directory path: '/admin/templates' }
275
+
276
+ let(:htaccess) { file path: '/.htaccess', size: 88 }
277
+ let(:favicon) { file path: '/favicon.ico', size: 1406 }
278
+ let(:index_php) { file path: '/index.php', size: 204 }
279
+
280
+ let(:remote_configs) { double lib::Remote::Configs }
281
+
282
+ let(:layout_theme_dir) { directory path: '/layout/themes/fb' }
283
+
284
+ before(:each) do
285
+ allow(remote)
286
+ .to receive(:root)
287
+ .and_return(root_dir)
288
+
289
+ allow(root_dir)
290
+ .to receive(:list)
291
+ .and_return []
292
+
293
+ allow(remote)
294
+ .to receive(:configs)
295
+ .and_return(remote_configs)
296
+
297
+ allow(remote_configs)
298
+ .to receive(:[])
299
+ .and_return(double 'remote-config', { name: 'theme', value: 'fb' })
300
+
301
+ allow(remote)
302
+ .to receive(:directory)
303
+ .with('/layout/themes/fb')
304
+ .and_return(layout_theme_dir)
305
+ end
306
+
307
+ it 'informs #logger about the starting task' do
308
+ expect(logger_mock)
309
+ .to receive(:puts)
310
+ .with('>> Downloading application sources...', :yellow)
311
+
312
+ clone_sources!
313
+ end
314
+
315
+ it 'goes through a remote directories recursively' do
316
+ expect(root_dir).to receive(:list).and_return [admin_dir]
317
+ expect(admin_dir).to receive(:list).and_return [templates_dir]
318
+ expect(templates_dir).to receive(:list).and_return []
319
+
320
+ clone_sources!
321
+ end
322
+
323
+ it 'informs #logger about each processing directory' do
324
+ allow(root_dir).to receive(:list).and_return [admin_dir]
325
+ allow(admin_dir).to receive(:list).and_return [templates_dir]
326
+
327
+ expect(logger_mock).to receive(:entry).with(admin_dir)
328
+ expect(logger_mock).to receive(:entry).with(templates_dir)
329
+
330
+ clone_sources!
331
+ end
332
+
333
+ %w[ $external_c
334
+ $internal_c
335
+ $userfiles
336
+ $userfiles/tmp
337
+ cgi-bin
338
+ external_c
339
+ internal_c
340
+ layout/themes
341
+ m/application/cache/smarty_compile
342
+ userfiles
343
+ userfiles/tmp
344
+ ].each do |entry|
345
+ it "skips `/#{entry}`" do
346
+ entry_dir = directory(:path => "/#{entry}")
347
+ expect(root_dir).to receive(:list).and_return [ entry_dir ]
348
+ expect(entry_dir).to_not receive(:list)
349
+
350
+ expect(logger_mock)
351
+ .to receive(:entry)
352
+ .with(entry_dir, :skipped, 'skipped by pathname')
353
+
354
+ clone_sources!
355
+ end
356
+ end
357
+
358
+ it 'downloads files listed in remote directories' do
359
+ root_dir_files = [ htaccess, favicon, index_php ]
360
+
361
+ expect(root_dir).to receive(:list)
362
+ .and_return(root_dir_files)
363
+
364
+ root_dir_files.each do |file|
365
+ expect(file).to receive(:save_as)
366
+ .with("/path/to/skadate#{file.path}")
367
+ end
368
+
369
+ clone_sources!
370
+ end
371
+
372
+ it 'informs #logger about each downloading file and status' do
373
+ allow(root_dir)
374
+ .to receive(:list)
375
+ .and_return [ htaccess, favicon, index_php ]
376
+
377
+ allow(htaccess)
378
+ .to receive(:save_as)
379
+ .with('/path/to/skadate/.htaccess')
380
+ .and_return(true)
381
+
382
+ expect(logger_mock)
383
+ .to receive(:entry)
384
+ .with(htaccess) do |&block|
385
+ expect(block.call).to eq :downloaded
386
+ end
387
+
388
+ allow(favicon)
389
+ .to receive(:save_as)
390
+ .with('/path/to/skadate/favicon.ico')
391
+ .and_return(false)
392
+
393
+ expect(logger_mock)
394
+ .to receive(:entry)
395
+ .with(favicon) do |&block|
396
+ expect(block.call).to eq :unchanged
397
+ end
398
+
399
+ clone_sources!
400
+ end
401
+
402
+ %w[ /archive1.tar.bz2
403
+ /archive2.tar.gz
404
+ /path/to/dir/archive3.zip
405
+ /folder/archive4.rar
406
+ ].each do |file_path|
407
+ it "skips `#{file_path}` by '*#{File.extname(file_path)}'" do
408
+ entry_file = file(path: file_path)
409
+
410
+ allow(root_dir)
411
+ .to receive(:list)
412
+ .and_return [ entry_file ]
413
+
414
+ expect(logger_mock)
415
+ .to receive(:entry)
416
+ .with(entry_file, :skipped, "skipped by (*#{File.extname(file_path)})")
417
+ .and_yield
418
+
419
+ expect(entry_file).to_not receive(:save_as)
420
+
421
+ clone_sources!
422
+ end
423
+ end
424
+
425
+ it 'skips files which size > `MAX_SOURCE_FILE_SIZE`' do
426
+ big_file = file path: 'install/skadate9.sql',
427
+ size: Remote::MAX_SOURCE_FILE_SIZE + 1
428
+
429
+ allow(root_dir)
430
+ .to receive(:list)
431
+ .and_return [ big_file ]
432
+
433
+ expect(logger_mock)
434
+ .to receive(:entry)
435
+ .with(big_file, :skipped, 'skipped by filesize')
436
+ .and_yield
437
+
438
+ expect(big_file).to_not receive(:save_as)
439
+
440
+ clone_sources!
441
+ end
442
+
443
+ context 'for a file which size exceeds `SHOW_PROGRESS_FILE_SIZE`' do
444
+ it 'creates and handles the `ruby-progressbar`' do
445
+ remote_file = file path: '/games/1234_5678_90.swf',
446
+ size: Remote::SHOW_PROGRESS_FILE_SIZE + 1
447
+
448
+ allow(root_dir)
449
+ .to receive(:list)
450
+ .and_return [ remote_file ]
451
+
452
+ expect(remote_file)
453
+ .to receive(:save_as)
454
+ .with('/path/to/skadate/games/1234_5678_90.swf') do |&block|
455
+ if block
456
+ block.call(1234)
457
+ block.call(5678)
458
+ end
459
+ end
460
+
461
+ pb_mock = double
462
+
463
+ expect(ProgressBar)
464
+ .to receive(:create) do |options|
465
+ expect(options[:title]).to eq '1234_5678_90.swf'
466
+ expect(options[:starting_at]).to eq 1234
467
+ pb_mock
468
+ end
469
+
470
+ expect(pb_mock)
471
+ .to receive(:progress)
472
+ .and_return(1234)
473
+
474
+ expect(pb_mock)
475
+ .to receive(:progress=)
476
+ .with(6912)
477
+
478
+ clone_sources!
479
+ end
480
+ end
481
+ end
482
+
483
+ describe '--database' do
484
+ def clone_database!
485
+ clone! %w[--database]
486
+ end
487
+
488
+ let(:remote_sql_dump) do
489
+ file path: 'external_c/1234567890.sql',
490
+ size: 1024 * 1024 * 30
491
+ end
492
+
493
+ before(:each) do
494
+ allow(remote).to receive(:create_mysql_dump)
495
+ .and_yield(remote_sql_dump)
496
+ end
497
+
498
+ it 'informs #logger about the starting task' do
499
+ expect(logger_mock)
500
+ .to receive(:puts)
501
+ .with('>> Creating remote database dump...', :yellow)
502
+
503
+ clone_database!
504
+ end
505
+
506
+ it 'requests remote database dump creation' do
507
+ expect(remote).to receive(:create_mysql_dump)
508
+ clone! %w[--database]
509
+ end
510
+
511
+ it 'downloads and saves a created dump as `remote-db-clone.sql`' do
512
+ expect(remote_sql_dump)
513
+ .to receive(:save_as)
514
+ .with('/path/to/skadate/remote-db-clone.sql') do |&block|
515
+ block.call(1234)
516
+ block.call(5678)
517
+ end
518
+
519
+ progressbar = double
520
+
521
+ expect(ProgressBar)
522
+ .to receive(:create)
523
+ .and_return(progressbar)
524
+
525
+ expect(progressbar)
526
+ .to receive(:progress)
527
+ .and_return(1234)
528
+
529
+ expect(progressbar)
530
+ .to receive(:progress=)
531
+ .with(6912)
532
+
533
+ clone_database!
534
+ end
535
+
536
+ context 'when dump file is compressed (tar.gz)' do
537
+ let(:remote_sql_dump) do
538
+ file path: 'external_c/12345.tar.gz',
539
+ size: 1024 * 1024 * 15
540
+ end
541
+
542
+ it 'downloads and saves file as `remote-db-clone.tar.gz`' do
543
+ expect(remote_sql_dump).to receive(:save_as)
544
+ .with('/path/to/skadate/remote-db-clone.tar.gz')
545
+
546
+ clone_database!
547
+ end
548
+ end
549
+ end
550
+
551
+ describe '--userfiles' do
552
+ def clone_userfiles!
553
+ clone! %w[--userfiles]
554
+ end
555
+
556
+ let(:list) {[
557
+ file(path: '/userfiles/full_size_2047_5625_42.jpg'),
558
+ file(path: '/userfiles/gift_25_1262767083.jpg'),
559
+ file(path: '/userfiles/sp.gif')
560
+ ]}
561
+
562
+ let(:userfiles) { directory path: '/userfiles' }
563
+
564
+ before(:each) do
565
+ allow(remote)
566
+ .to receive(:userfiles)
567
+ .and_return(userfiles)
568
+
569
+ allow(userfiles)
570
+ .to receive(:list)
571
+ .and_return(list)
572
+ end
573
+
574
+ it 'informs #logger about the starting task' do
575
+ expect(logger_mock)
576
+ .to receive(:puts)
577
+ .with('>> Detecting `$userfiles` directory...', :yellow)
578
+
579
+ clone_userfiles!
580
+ end
581
+
582
+ it 'uses Remote#userfiles to detect `$userfiles` directory' do
583
+ expect(remote)
584
+ .to receive(:userfiles)
585
+ .and_return(userfiles)
586
+
587
+ clone_userfiles!
588
+ end
589
+
590
+ it 'downloads `$userfiles` directory contents' do
591
+ list.each do |file|
592
+ expect(file).to receive(:save_as)
593
+ .with("/path/to/skadate#{file.path}") do |&block|
594
+ if block
595
+ block.call(123)
596
+ block.call(456)
597
+ end
598
+ end
599
+ end
600
+
601
+ clone_userfiles!
602
+ end
603
+
604
+ it 'skips `$userfiles/tmp` directory entry' do
605
+ tmpdir = directory(path: '/userfiles/tmp')
606
+ list << tmpdir
607
+
608
+ expect(logger_mock)
609
+ .to receive(:entry)
610
+ .with(tmpdir, :skipped, 'skipped by pathname')
611
+ .and_yield
612
+
613
+ expect(tmpdir).to_not receive(:list)
614
+
615
+ clone_userfiles!
616
+ end
617
+ end
618
+
619
+ end
620
+ end
621
+
622
+ end
623
+ end