gitdocs 0.5.0 → 0.6.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.
- checksums.yaml +6 -14
- data/.codeclimate.yml +26 -0
- data/.rubocop.yml +8 -2
- data/.travis.yml +8 -0
- data/CHANGELOG +13 -0
- data/Gemfile +1 -1
- data/README.md +7 -6
- data/Rakefile +31 -5
- data/bin/gitdocs +1 -0
- data/config.ru +6 -4
- data/gitdocs.gemspec +22 -19
- data/lib/gitdocs.rb +54 -16
- data/lib/gitdocs/browser_app.rb +34 -41
- data/lib/gitdocs/cli.rb +41 -32
- data/lib/gitdocs/configuration.rb +40 -101
- data/lib/gitdocs/git_notifier.rb +111 -0
- data/lib/gitdocs/initializer.rb +83 -0
- data/lib/gitdocs/manager.rb +90 -60
- data/lib/gitdocs/migration/004_add_index_for_path.rb +1 -1
- data/lib/gitdocs/notifier.rb +70 -104
- data/lib/gitdocs/rendering_helper.rb +3 -0
- data/lib/gitdocs/repository.rb +324 -307
- data/lib/gitdocs/repository/committer.rb +77 -0
- data/lib/gitdocs/repository/path.rb +157 -140
- data/lib/gitdocs/search.rb +40 -25
- data/lib/gitdocs/settings_app.rb +5 -3
- data/lib/gitdocs/share.rb +64 -0
- data/lib/gitdocs/synchronizer.rb +40 -0
- data/lib/gitdocs/version.rb +1 -1
- data/lib/gitdocs/views/_header.haml +2 -2
- data/lib/gitdocs/views/dir.haml +3 -3
- data/lib/gitdocs/views/edit.haml +1 -1
- data/lib/gitdocs/views/file.haml +1 -1
- data/lib/gitdocs/views/home.haml +3 -3
- data/lib/gitdocs/views/layout.haml +13 -13
- data/lib/gitdocs/views/revisions.haml +3 -3
- data/lib/gitdocs/views/search.haml +1 -1
- data/lib/gitdocs/views/settings.haml +6 -6
- data/test/integration/cli/full_sync_test.rb +83 -0
- data/test/integration/cli/share_management_test.rb +29 -0
- data/test/integration/cli/status_test.rb +14 -0
- data/test/integration/test_helper.rb +185 -151
- data/test/integration/{browse_test.rb → web/browse_test.rb} +11 -29
- data/test/integration/web/share_management_test.rb +46 -0
- data/test/support/git_factory.rb +276 -0
- data/test/unit/browser_app_test.rb +346 -0
- data/test/unit/configuration_test.rb +8 -70
- data/test/unit/git_notifier_test.rb +116 -0
- data/test/unit/gitdocs_test.rb +90 -0
- data/test/unit/manager_test.rb +36 -0
- data/test/unit/notifier_test.rb +60 -124
- data/test/unit/repository_committer_test.rb +111 -0
- data/test/unit/repository_path_test.rb +92 -76
- data/test/unit/repository_test.rb +243 -356
- data/test/unit/search_test.rb +15 -0
- data/test/unit/settings_app_test.rb +80 -0
- data/test/unit/share_test.rb +97 -0
- data/test/unit/test_helper.rb +17 -3
- metadata +114 -108
- data/lib/gitdocs/runner.rb +0 -108
- data/lib/gitdocs/server.rb +0 -62
- data/test/integration/full_sync_test.rb +0 -66
- data/test/integration/share_management_test.rb +0 -95
- data/test/integration/status_test.rb +0 -21
- data/test/unit/runner_test.rb +0 -122
@@ -2,56 +2,57 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'minitest/autorun'
|
5
|
-
$LOAD_PATH.unshift File.expand_path('../../lib')
|
6
|
-
require 'gitdocs'
|
7
5
|
require 'aruba'
|
8
6
|
require 'aruba/api'
|
9
7
|
require 'timeout'
|
10
8
|
require 'capybara'
|
11
9
|
require 'capybara_minitest_spec'
|
10
|
+
require 'capybara/dsl'
|
12
11
|
require 'capybara/poltergeist'
|
12
|
+
require 'find'
|
13
|
+
require 'gitdocs/version'
|
14
|
+
Dir.glob(File.expand_path('../../support/**/*.rb', __FILE__)).each do |filename|
|
15
|
+
require_relative filename
|
16
|
+
end
|
13
17
|
|
14
|
-
Capybara.app_host
|
15
|
-
Capybara.default_driver
|
16
|
-
Capybara.run_server
|
17
|
-
Capybara.
|
18
|
+
Capybara.app_host = 'http://localhost:7777/'
|
19
|
+
Capybara.default_driver = :poltergeist
|
20
|
+
Capybara.run_server = false
|
21
|
+
Capybara.default_max_wait_time = ENV['TRAVIS'] ? 120 : 30
|
18
22
|
|
19
23
|
Capybara.register_driver :poltergeist do |app|
|
20
|
-
Capybara::Poltergeist::Driver.new(
|
24
|
+
Capybara::Poltergeist::Driver.new(
|
25
|
+
app,
|
26
|
+
timeout: Capybara.default_max_wait_time,
|
27
|
+
# Disable catching javascript errors because of the possibility of errors
|
28
|
+
# from the Ace code.
|
29
|
+
js_errors: false
|
30
|
+
)
|
21
31
|
end
|
22
32
|
|
23
|
-
|
24
|
-
class ArubaApiWrapper
|
25
|
-
include Aruba::Api
|
26
|
-
end
|
33
|
+
PID_FILE = File.expand_path('../../../tmp/gitdocs.pid', __FILE__)
|
27
34
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
def run(*args)
|
33
|
-
if args.length == 0
|
34
|
-
super
|
35
|
-
else
|
36
|
-
aruba.run(*args)
|
35
|
+
module MiniTest
|
36
|
+
module Aruba
|
37
|
+
class ArubaApiWrapper
|
38
|
+
include ::Aruba::Api
|
37
39
|
end
|
38
|
-
end
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
41
|
+
def aruba
|
42
|
+
@aruba ||= ArubaApiWrapper.new
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def run(*args)
|
46
|
+
if args.empty?
|
47
|
+
super
|
48
|
+
else
|
49
|
+
aruba.run(*args)
|
50
|
+
end
|
51
|
+
end
|
50
52
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
processes.clear
|
53
|
+
def method_missing(method, *args, &block)
|
54
|
+
aruba.send(method, *args, &block)
|
55
|
+
end
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
@@ -61,9 +62,30 @@ module Helper
|
|
61
62
|
include Capybara::RSpecMatchers
|
62
63
|
|
63
64
|
def before_setup
|
64
|
-
|
65
|
+
clean_current_dir
|
66
|
+
|
67
|
+
# HACK: In order to ensure that rugged/libgit2 see the expected HOME
|
68
|
+
# directory we must set it before requiring rugged. This seems to occur
|
69
|
+
# because libgit2 reads HOME only one the initial load.
|
65
70
|
set_env('HOME', abs_current_dir)
|
66
|
-
|
71
|
+
require 'rugged'
|
72
|
+
|
73
|
+
# Make sure that we are not accidentally overwriting an existing gitconfig.
|
74
|
+
if Rugged::Config.global['user.name'] || Rugged::Config.global['user.name']
|
75
|
+
puts <<-EOS.gsub(/^\s{8}/, '')
|
76
|
+
Unexpected git config:
|
77
|
+
user.name = #{Rugged::Config.global['user.name']}
|
78
|
+
user.email = #{Rugged::Config.global['user.email']}
|
79
|
+
Something went wrong when setting the HOME directory and the test
|
80
|
+
will not execute in isolation.'
|
81
|
+
EXITING
|
82
|
+
EOS
|
83
|
+
exit
|
84
|
+
end
|
85
|
+
|
86
|
+
GitFactory.working_directory = abs_current_dir
|
87
|
+
Rugged::Config.global['user.name'] = GitFactory.users[0][:name]
|
88
|
+
Rugged::Config.global['user.email'] = GitFactory.users[0][:email]
|
67
89
|
end
|
68
90
|
|
69
91
|
def teardown
|
@@ -72,33 +94,85 @@ module Helper
|
|
72
94
|
end
|
73
95
|
|
74
96
|
def after_teardown
|
75
|
-
|
97
|
+
restore_env
|
98
|
+
processes.clear
|
76
99
|
|
77
100
|
terminate_processes!
|
78
101
|
prep_for_fs_check do
|
79
|
-
next unless File.exist?(
|
102
|
+
next unless File.exist?(PID_FILE)
|
103
|
+
|
104
|
+
pid = IO.read(PID_FILE).to_i
|
105
|
+
begin
|
106
|
+
Process.kill('KILL', pid)
|
107
|
+
rescue Errno::ESRCH # rubocop:disable Lint/HandleExceptions
|
108
|
+
# Nothing to do since the process is already gone.
|
109
|
+
end
|
80
110
|
|
81
|
-
pid = IO.read('gitdocs.pid').to_i
|
82
|
-
Process.kill('KILL', pid)
|
83
111
|
begin
|
84
112
|
Process.wait(pid)
|
85
113
|
rescue SystemCallError # rubocop:disable Lint/HandleExceptions
|
86
114
|
# This means that the process is already gone.
|
87
115
|
# Nothing to do.
|
88
116
|
end
|
117
|
+
FileUtils.rm_rf(PID_FILE)
|
118
|
+
end
|
119
|
+
|
120
|
+
return if passed?
|
121
|
+
|
122
|
+
# Report gitdocs execution details on failure
|
123
|
+
puts "\n\n----------------------------------"
|
124
|
+
puts "Aruba details for failure: #{name}"
|
125
|
+
puts failures.inspect.to_s
|
126
|
+
|
127
|
+
log_filename = File.join(abs_current_dir, '.gitdocs', 'log')
|
128
|
+
if File.exist?(log_filename)
|
129
|
+
puts '----------------------------------'
|
130
|
+
puts "Log file: #{log_filename}"
|
131
|
+
puts File.read(log_filename)
|
132
|
+
end
|
133
|
+
|
134
|
+
if Dir.exist?(abs_current_dir)
|
135
|
+
puts '----------------------------------'
|
136
|
+
puts 'Aruba current directory file list:'
|
137
|
+
Find.find(abs_current_dir) do |path|
|
138
|
+
Find.prune if path =~ %r{.git/?$}
|
139
|
+
puts " #{path}"
|
140
|
+
end
|
89
141
|
end
|
142
|
+
|
143
|
+
puts "----------------------------------\n\n"
|
90
144
|
end
|
91
145
|
|
92
|
-
|
93
|
-
|
94
|
-
|
146
|
+
# @param [String] method pass to the CLI
|
147
|
+
# @param [String] arguments which will be passed to the CLI in addition
|
148
|
+
# @param [String] expected_output that the CLI should return
|
149
|
+
#
|
150
|
+
# @return [String] full text of the command being executed
|
151
|
+
def gitdocs_command(method, arguments, expected_output)
|
152
|
+
binary_path = File.expand_path('../../../bin/gitdocs', __FILE__)
|
153
|
+
full_command = "#{binary_path} #{method} #{arguments} --pid=#{PID_FILE}"
|
154
|
+
|
155
|
+
run(full_command, Capybara.default_max_wait_time)
|
156
|
+
assert_success(true)
|
157
|
+
assert_partial_output(expected_output, output_from(full_command))
|
158
|
+
|
159
|
+
full_command
|
160
|
+
end
|
161
|
+
|
162
|
+
# @return [void]
|
163
|
+
def gitdocs_start
|
164
|
+
# FIXME: Calling internal funcations directly because we cannot currently
|
165
|
+
# set polling or notification on the CLI. After that has been added this
|
166
|
+
# should be removed. [ASC 2015-10-26]
|
167
|
+
require 'gitdocs/initializer'
|
168
|
+
require 'gitdocs/share'
|
169
|
+
Gitdocs::Initializer.initialize_database
|
170
|
+
Gitdocs::Share.all.each do |share|
|
95
171
|
share.update_attributes(polling_interval: 0.1, notification: false)
|
96
172
|
end
|
97
173
|
|
98
|
-
|
99
|
-
|
100
|
-
assert_success(true)
|
101
|
-
assert_partial_output('Started gitdocs', output_from(start_cmd))
|
174
|
+
FileUtils.rm_rf(PID_FILE)
|
175
|
+
gitdocs_command('start', '--verbose --port=7777', 'Started gitdocs')
|
102
176
|
end
|
103
177
|
|
104
178
|
# @overload abs_current_dir
|
@@ -111,128 +185,88 @@ module Helper
|
|
111
185
|
File.absolute_path(File.join(current_dir, relative_path))
|
112
186
|
end
|
113
187
|
|
114
|
-
# @
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
188
|
+
# @param [String] path
|
189
|
+
#
|
190
|
+
# @return [#gitdocs_command]
|
191
|
+
def gitdocs_add(path)
|
192
|
+
GitFactory.init(path)
|
193
|
+
gitdocs_command('add', path, "Added path #{path} to doc list")
|
119
194
|
end
|
120
195
|
|
121
|
-
# @
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
rugged = Rugged::Repository.new(abs_current_dir(path))
|
135
|
-
dirty = !rugged.diff_workdir(rugged.head.target, include_untracked: true).deltas.empty?
|
136
|
-
rescue Rugged::ReferenceError
|
137
|
-
nil
|
138
|
-
rescue Rugged::InvalidError
|
139
|
-
nil
|
140
|
-
rescue Rugged::RepositoryError
|
141
|
-
nil
|
142
|
-
end
|
143
|
-
end
|
196
|
+
# @param [Array<String>] destination_paths
|
197
|
+
#
|
198
|
+
# @return [void]
|
199
|
+
def gitdocs_create_from_remote(*destination_paths)
|
200
|
+
full_destination_paths = destination_paths.map { |x| GitFactory.expand_path(x) }
|
201
|
+
remote_repository_path = GitFactory.init_bare(:remote)
|
202
|
+
|
203
|
+
full_destination_paths.each do |destination_path|
|
204
|
+
gitdocs_command(
|
205
|
+
'create',
|
206
|
+
"#{destination_path} #{remote_repository_path}",
|
207
|
+
"Added path #{destination_path} to doc list"
|
208
|
+
)
|
144
209
|
end
|
145
|
-
rescue Timeout::Error
|
146
|
-
assert(false, "#{path} workdir is still dirty")
|
147
210
|
end
|
148
211
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
nil
|
157
|
-
end
|
158
|
-
|
159
|
-
assert(File.exist?(file), "Missing #{file}")
|
160
|
-
actual_content = IO.read(file)
|
161
|
-
assert(
|
162
|
-
actual_content == exact_content,
|
163
|
-
"Expected #{file} content: #{exact_content}\nActual content #{actual_content}"
|
164
|
-
)
|
212
|
+
# @param [Array<String>] expected_outputs
|
213
|
+
#
|
214
|
+
# @return [void]
|
215
|
+
def gitdocs_assert_status_contains(*expected_outputs)
|
216
|
+
command = gitdocs_command('status', '', Gitdocs::VERSION)
|
217
|
+
expected_outputs.each do |expected_output|
|
218
|
+
assert_partial_output(expected_output, output_from(command))
|
165
219
|
end
|
166
220
|
end
|
167
221
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
assert(Dir.exist?(path), "Missing #{path}")
|
222
|
+
# @param [Array<String>] not_expected_outputs
|
223
|
+
#
|
224
|
+
# @return [void]
|
225
|
+
def gitdocs_assert_status_not_contain(*not_expected_outputs)
|
226
|
+
command = gitdocs_command('status', '', Gitdocs::VERSION)
|
227
|
+
not_expected_outputs.each do |not_expected_output|
|
228
|
+
assert_no_partial_output(not_expected_output, output_from(command))
|
177
229
|
end
|
178
230
|
end
|
179
231
|
|
180
|
-
|
181
|
-
|
232
|
+
# @overload wait_for_assert
|
233
|
+
# @yield to a block which executes Minitest assertion
|
234
|
+
#
|
235
|
+
# @overload wait_for_assert(interval)
|
236
|
+
# @param [Float] interval
|
237
|
+
# @yield to a block which executes Minitest assertion
|
238
|
+
#
|
239
|
+
# @raise [Minitest::Assertion]
|
240
|
+
#
|
241
|
+
# @return [void]
|
242
|
+
def wait_for_assert(interval = 0.1)
|
243
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
182
244
|
begin
|
183
|
-
|
184
|
-
rescue
|
185
|
-
|
186
|
-
|
187
|
-
assert(!File.exist?(path), "#{path} should have been removed")
|
188
|
-
end
|
189
|
-
|
190
|
-
begin
|
191
|
-
Timeout.timeout(20) { sleep(0.1) if Dir.glob("#{path} (*)").empty? }
|
192
|
-
rescue Timeout::Error
|
193
|
-
nil
|
194
|
-
ensure
|
195
|
-
assert(!Dir.glob("#{path} (*)").empty?, "#{path} conflict marks should have been created")
|
245
|
+
yield
|
246
|
+
rescue Minitest::Assertion, Capybara::Poltergeist::Error
|
247
|
+
sleep(interval)
|
248
|
+
retry
|
196
249
|
end
|
197
250
|
end
|
251
|
+
rescue Timeout::Error
|
252
|
+
yield
|
198
253
|
end
|
199
254
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
abs_clone_path = abs_current_dir(clone_path)
|
210
|
-
FileUtils.rm_rf(abs_clone_path)
|
211
|
-
repo = Rugged::Repository.clone_at(
|
212
|
-
"file://#{remote_path}",
|
213
|
-
abs_clone_path
|
214
|
-
)
|
215
|
-
repo.config['user.email'] = 'afish@example.com'
|
216
|
-
repo.config['user.name'] = 'Art T. Fish'
|
217
|
-
gitdocs_add(clone_path)
|
255
|
+
# @param [String] locator
|
256
|
+
#
|
257
|
+
# @raise [Minitest::Assertion]
|
258
|
+
#
|
259
|
+
# @return [void]
|
260
|
+
def visit_and_click_link(locator)
|
261
|
+
wait_for_assert(1) do
|
262
|
+
visit('http://localhost:7777/')
|
263
|
+
click_link(locator)
|
218
264
|
end
|
219
265
|
end
|
220
|
-
|
221
|
-
def gitdocs_status
|
222
|
-
@status_cmd = 'gitdocs status --pid=gitdocs.pid'
|
223
|
-
run(@status_cmd, 15)
|
224
|
-
assert_success(true)
|
225
|
-
end
|
226
|
-
|
227
|
-
def assert_gitdocs_status_contains(expected)
|
228
|
-
assert_partial_output(expected, output_from(@status_cmd))
|
229
|
-
end
|
230
|
-
|
231
|
-
def assert_gitdocs_status_not_contain(expected)
|
232
|
-
assert_no_partial_output(expected, output_from(@status_cmd))
|
233
|
-
end
|
234
266
|
end
|
235
267
|
|
236
|
-
|
237
|
-
|
268
|
+
module MiniTest
|
269
|
+
class Spec
|
270
|
+
include Helper
|
271
|
+
end
|
238
272
|
end
|
@@ -1,32 +1,22 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
|
3
|
-
require File.expand_path('
|
3
|
+
require File.expand_path('../../test_helper', __FILE__)
|
4
4
|
|
5
5
|
describe 'browse and edit repository file through the UI' do
|
6
6
|
before do
|
7
|
-
git_init_local('repo1')
|
8
7
|
gitdocs_add('repo1')
|
9
|
-
|
10
|
-
git_init_local
|
11
|
-
gitdocs_add
|
8
|
+
gitdocs_add('local')
|
12
9
|
|
13
10
|
# Create the various commits, to be able to see revisions.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
write_file('local/README.md', 'hello i am a README')
|
24
|
-
repository.commit
|
25
|
-
|
26
|
-
start_daemon
|
27
|
-
|
28
|
-
visit 'http://localhost:7777/'
|
29
|
-
click_link('Home')
|
11
|
+
GitFactory.commit(:local, 'file1', 'fbadbeef')
|
12
|
+
GitFactory.commit(:local, 'file1', 'foobar')
|
13
|
+
GitFactory.commit(:local, 'file1', 'deadbeef')
|
14
|
+
GitFactory.commit(:local, 'file2', 'A5A5A5A5')
|
15
|
+
GitFactory.commit(:local, 'README.md', 'hello i am a README')
|
16
|
+
|
17
|
+
gitdocs_start
|
18
|
+
visit_and_click_link('Home')
|
19
|
+
|
30
20
|
within('table#shares') do
|
31
21
|
within('tbody') do
|
32
22
|
click_link(abs_current_dir('local'))
|
@@ -59,10 +49,6 @@ describe 'browse and edit repository file through the UI' do
|
|
59
49
|
end
|
60
50
|
|
61
51
|
it 'should be able to browser a file revision' do
|
62
|
-
# FIXME: This test is failing on TravisCI, but succeeding locally so skip
|
63
|
-
# it for now and revisit in the future.
|
64
|
-
next if ENV['TRAVIS']
|
65
|
-
|
66
52
|
within('table#revisions') do
|
67
53
|
within('tbody') do
|
68
54
|
page.must_have_css('tr', count: 2)
|
@@ -77,10 +63,6 @@ describe 'browse and edit repository file through the UI' do
|
|
77
63
|
end
|
78
64
|
|
79
65
|
it 'should allow file revert' do
|
80
|
-
# FIXME: This test is failing on TravisCI, but succeeding locally so skip
|
81
|
-
# it for now and revisit in the future.
|
82
|
-
next if ENV['TRAVIS']
|
83
|
-
|
84
66
|
within('table#revisions') do
|
85
67
|
within('tbody') do
|
86
68
|
page.must_have_css('tr', count: 2)
|