ohloh_scm 4.0.5 → 5.0.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.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +14 -3
  3. data/.ruby-version +1 -1
  4. data/Dockerfile +8 -8
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +48 -33
  7. data/lib/ohloh_scm/activity.rb +1 -1
  8. data/lib/ohloh_scm/bzr/activity.rb +12 -12
  9. data/lib/ohloh_scm/bzr/validation.rb +1 -1
  10. data/lib/ohloh_scm/commit.rb +2 -4
  11. data/lib/ohloh_scm/core.rb +2 -1
  12. data/lib/ohloh_scm/cvs/activity.rb +74 -60
  13. data/lib/ohloh_scm/cvs/scm.rb +12 -12
  14. data/lib/ohloh_scm/cvs/status.rb +1 -1
  15. data/lib/ohloh_scm/cvs/validation.rb +3 -3
  16. data/lib/ohloh_scm/diff.rb +1 -1
  17. data/lib/ohloh_scm/factory.rb +7 -1
  18. data/lib/ohloh_scm/git/activity.rb +111 -55
  19. data/lib/ohloh_scm/git/scm.rb +6 -8
  20. data/lib/ohloh_scm/git/status.rb +1 -1
  21. data/lib/ohloh_scm/git/validation.rb +1 -1
  22. data/lib/ohloh_scm/git_svn/activity.rb +5 -5
  23. data/lib/ohloh_scm/git_svn/scm.rb +5 -5
  24. data/lib/ohloh_scm/hg/activity.rb +13 -13
  25. data/lib/ohloh_scm/hg/scm.rb +3 -3
  26. data/lib/ohloh_scm/hg/validation.rb +1 -1
  27. data/lib/ohloh_scm/parser/branch_number.rb +7 -6
  28. data/lib/ohloh_scm/parser/bzr_xml_parser.rb +15 -15
  29. data/lib/ohloh_scm/parser/cvs_parser.rb +7 -6
  30. data/lib/ohloh_scm/parser/git_parser.rb +18 -15
  31. data/lib/ohloh_scm/parser/hg_parser.rb +8 -6
  32. data/lib/ohloh_scm/parser/svn_parser.rb +7 -6
  33. data/lib/ohloh_scm/py_bridge/hg_client.rb +1 -1
  34. data/lib/ohloh_scm/svn/activity.rb +17 -18
  35. data/lib/ohloh_scm/svn/scm.rb +4 -6
  36. data/lib/ohloh_scm/svn/validation.rb +2 -2
  37. data/lib/ohloh_scm/system.rb +1 -1
  38. data/lib/ohloh_scm/validation.rb +2 -4
  39. data/lib/ohloh_scm/version.rb +1 -1
  40. data/ohloh_scm.gemspec +5 -5
  41. data/spec/.rubocop.yml +2 -5
  42. data/spec/benchmarks/process_spawn_benchmark.rb +1 -1
  43. data/spec/helpers/assert_scm_attr_helper.rb +4 -4
  44. data/spec/helpers/generic_helper.rb +2 -2
  45. data/spec/helpers/repository_helper.rb +1 -1
  46. data/spec/ohloh_scm/activity_spec.rb +2 -2
  47. data/spec/ohloh_scm/bzr/activity_spec.rb +60 -60
  48. data/spec/ohloh_scm/bzr/validation_spec.rb +1 -1
  49. data/spec/ohloh_scm/cvs/activity_spec.rb +20 -21
  50. data/spec/ohloh_scm/cvs/scm_spec.rb +36 -36
  51. data/spec/ohloh_scm/cvs/validation_spec.rb +4 -4
  52. data/spec/ohloh_scm/factory_spec.rb +2 -2
  53. data/spec/ohloh_scm/git/activity_spec.rb +111 -110
  54. data/spec/ohloh_scm/git/scm_spec.rb +11 -11
  55. data/spec/ohloh_scm/git/status_spec.rb +3 -3
  56. data/spec/ohloh_scm/git/validation_spec.rb +7 -7
  57. data/spec/ohloh_scm/git_svn/activity_spec.rb +14 -14
  58. data/spec/ohloh_scm/git_svn/scm_spec.rb +1 -1
  59. data/spec/ohloh_scm/hg/activity_spec.rb +99 -99
  60. data/spec/ohloh_scm/hg/scm_spec.rb +5 -5
  61. data/spec/ohloh_scm/hg/validation_spec.rb +1 -1
  62. data/spec/ohloh_scm/parser/array_writer_spec.rb +7 -7
  63. data/spec/ohloh_scm/parser/branch_number_spec.rb +3 -3
  64. data/spec/ohloh_scm/parser/cvs_parser_spec.rb +31 -31
  65. data/spec/ohloh_scm/parser/git_parser_spec.rb +29 -32
  66. data/spec/ohloh_scm/parser/hg_parser_spec.rb +60 -60
  67. data/spec/ohloh_scm/svn/activity_spec.rb +11 -12
  68. data/spec/ohloh_scm/svn/scm_spec.rb +24 -24
  69. data/spec/ohloh_scm/svn/validation_spec.rb +6 -6
  70. data/spec/ohloh_scm/svn_parser_spec.rb +29 -29
  71. data/spec/ohloh_scm/system_spec.rb +5 -5
  72. data/spec/ohloh_scm/version_spec.rb +1 -1
  73. data/spec/string_encoder_spec.rb +4 -4
  74. metadata +5 -79
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9173a903d32cdd9d100594a9077f7528d473a8cb9c7f1dcf7172745184f2f2f0
4
- data.tar.gz: d6b967d7648cb2bdbc5c594d8c119c8f533d945b3b608aaef87bd2f4b8c67322
3
+ metadata.gz: 0517dea873b5829d942367af3ec07ec0497b405d30a757791cfed1778a281cd8
4
+ data.tar.gz: fb5146be6537fa90b3fe611f37a48b34614768a4c5d52223ca72b83c1dbef717
5
5
  SHA512:
6
- metadata.gz: 904efa77cf2a35d8de044afc5c8fb16f9266465e8d4fdf04ef403ccc093983a16fb76b0a40791f6033c4e767c2c598df0c79dfcb15f33e29e6fee4d00a3f9a6d
7
- data.tar.gz: cd232f7a7bff3c4384160e04952cddf0ac54680d34c4e84ad44bc7874be6cec4d42d5007a8d41513a1e54afb1c3a1b9be8b32b021e76308b2a3992a8712ea7b4
6
+ metadata.gz: 93001e6affa4f9e2ae96767d6a23d29527f74f76d64b01c015f0ddb7689d187b6d62857f33c8961a316823cb283838e1ee65fab472102b9d0ef601d457b68d0c
7
+ data.tar.gz: a6fe592ecaf5e5d848d12684dbbd50b35a7657c22579932c0dc08c0613f9d6369ce314df730cbebd591e56c2ddba7bfbab63887981f9fe1a706812d6de9107fa
data/.rubocop.yml CHANGED
@@ -1,12 +1,14 @@
1
1
  require: rubocop-performance
2
2
 
3
3
  AllCops:
4
- TargetRubyVersion: 2.5
4
+ TargetRubyVersion: 3.0
5
+ NewCops: enable
6
+ SuggestExtensions: false
5
7
 
6
- Metrics/LineLength:
8
+ Layout/LineLength:
7
9
  Max: 99
8
10
 
9
- Documentation:
11
+ Style/Documentation:
10
12
  Enabled: false
11
13
 
12
14
  Style/RegexpLiteral:
@@ -14,3 +16,12 @@ Style/RegexpLiteral:
14
16
 
15
17
  Metrics/ClassLength:
16
18
  Enabled: false
19
+
20
+ Lint/MissingSuper:
21
+ Enabled: false
22
+
23
+ Style/OptionalBooleanParameter:
24
+ Enabled: false
25
+
26
+ Metrics/AbcSize:
27
+ Enabled: true
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.9
1
+ 3.1.7
data/Dockerfile CHANGED
@@ -1,11 +1,11 @@
1
1
  FROM ubuntu:22.04
2
- MAINTAINER OpenHub <info@openhub.net>
2
+ LABEL maintainer="OpenHub <info@openhub.net>"
3
3
 
4
- ENV HOME /home
5
- ENV LC_ALL en_US.UTF-8
6
- ENV APP_HOME $HOME/app/ohloh_scm
7
- ENV DEBIAN_FRONTEND noninteractive
8
- ENV PATH $HOME/.rbenv/shims:$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin:$PATH
4
+ ENV HOME=/home
5
+ ENV LC_ALL=en_US.UTF-8
6
+ ENV APP_HOME=$HOME/app/ohloh_scm
7
+ ENV DEBIAN_FRONTEND=noninteractive
8
+ ENV PATH=$HOME/.rbenv/shims:$HOME/.rbenv/bin:$HOME/.rbenv/plugins/ruby-build/bin:$PATH
9
9
 
10
10
  RUN apt-get update
11
11
  RUN apt-get install -y build-essential software-properties-common locales ragel \
@@ -23,7 +23,7 @@ RUN cd $HOME \
23
23
  && echo 'eval "$(rbenv init -)"' >> $HOME/.bashrc \
24
24
  && echo 'gem: --no-rdoc --no-ri' >> $HOME/.gemrc \
25
25
  && echo 'export PATH="$HOME/.rbenv/shims:$HOME/.rbenv/bin:/home/.rbenv/plugins/ruby-build/bin:$PATH"' >> $HOME/.bash_profile \
26
- && rbenv install 2.6.9 && rbenv global 2.6.9
26
+ && rbenv install 3.1.7 && rbenv global 3.1.7
27
27
 
28
28
  RUN git config --global --add safe.directory '*'
29
29
 
@@ -41,7 +41,7 @@ RUN ln -s /usr/bin/cvs /usr/bin/cvsnt
41
41
  # Run bundle install before copying source to keep this step cached.
42
42
  RUN mkdir -p $APP_HOME
43
43
  COPY Gemfile* $APP_HOME/
44
- RUN gem install rake bundler:1.17.3 \
44
+ RUN gem install rake bundler:2.6.9 \
45
45
  && bundle config --global silence_root_warning 1 \
46
46
  && cd $APP_HOME && bundle install
47
47
 
data/Gemfile CHANGED
@@ -8,7 +8,7 @@ group :development do
8
8
  gem 'mocha'
9
9
  gem 'nokogiri'
10
10
  gem 'rake'
11
- gem 'rubocop', '~> 0.67'
11
+ gem 'rubocop', '>= 1.12.0'
12
12
  gem 'rubocop-performance'
13
13
  gem 'simplecov'
14
14
  end
data/Gemfile.lock CHANGED
@@ -1,41 +1,56 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- ast (2.4.0)
5
- byebug (11.0.1)
6
- docile (1.3.1)
7
- jaro_winkler (1.5.2)
8
- json (2.2.0)
9
- metaclass (0.0.4)
10
- mini_portile2 (2.4.0)
11
- minitest (5.11.3)
12
- mocha (1.8.0)
13
- metaclass (~> 0.0.1)
14
- nokogiri (1.10.3)
15
- mini_portile2 (~> 2.4.0)
16
- parallel (1.17.0)
17
- parser (2.6.2.1)
18
- ast (~> 2.4.0)
19
- psych (3.1.0)
20
- rainbow (3.0.0)
21
- rake (12.3.2)
22
- rubocop (0.67.2)
23
- jaro_winkler (~> 1.5.1)
4
+ ast (2.4.3)
5
+ byebug (12.0.0)
6
+ docile (1.4.1)
7
+ json (2.12.2)
8
+ language_server-protocol (3.17.0.5)
9
+ lint_roller (1.1.0)
10
+ mini_portile2 (2.8.9)
11
+ minitest (5.25.5)
12
+ mocha (2.7.1)
13
+ ruby2_keywords (>= 0.0.5)
14
+ nokogiri (1.18.8)
15
+ mini_portile2 (~> 2.8.2)
16
+ racc (~> 1.4)
17
+ parallel (1.27.0)
18
+ parser (3.3.8.0)
19
+ ast (~> 2.4.1)
20
+ racc
21
+ prism (1.4.0)
22
+ racc (1.8.1)
23
+ rainbow (3.1.1)
24
+ rake (13.2.1)
25
+ regexp_parser (2.10.0)
26
+ rubocop (1.75.8)
27
+ json (~> 2.3)
28
+ language_server-protocol (~> 3.17.0.2)
29
+ lint_roller (~> 1.1.0)
24
30
  parallel (~> 1.10)
25
- parser (>= 2.5, != 2.5.1.1)
26
- psych (>= 3.1.0)
31
+ parser (>= 3.3.0.2)
27
32
  rainbow (>= 2.2.2, < 4.0)
33
+ regexp_parser (>= 2.9.3, < 3.0)
34
+ rubocop-ast (>= 1.44.0, < 2.0)
28
35
  ruby-progressbar (~> 1.7)
29
- unicode-display_width (>= 1.4.0, < 1.6)
30
- rubocop-performance (1.1.0)
31
- rubocop (>= 0.67.0)
32
- ruby-progressbar (1.10.0)
33
- simplecov (0.16.1)
36
+ unicode-display_width (>= 2.4.0, < 4.0)
37
+ rubocop-ast (1.44.1)
38
+ parser (>= 3.3.7.2)
39
+ prism (~> 1.4)
40
+ rubocop-performance (1.10.2)
41
+ rubocop (>= 0.90.0, < 2.0)
42
+ rubocop-ast (>= 0.4.0)
43
+ ruby-progressbar (1.13.0)
44
+ ruby2_keywords (0.0.5)
45
+ simplecov (0.22.0)
34
46
  docile (~> 1.1)
35
- json (>= 1.8, < 3)
36
- simplecov-html (~> 0.10.0)
37
- simplecov-html (0.10.2)
38
- unicode-display_width (1.5.0)
47
+ simplecov-html (~> 0.11)
48
+ simplecov_json_formatter (~> 0.1)
49
+ simplecov-html (0.13.1)
50
+ simplecov_json_formatter (0.1.4)
51
+ unicode-display_width (3.1.4)
52
+ unicode-emoji (~> 4.0, >= 4.0.4)
53
+ unicode-emoji (4.0.4)
39
54
 
40
55
  PLATFORMS
41
56
  ruby
@@ -46,9 +61,9 @@ DEPENDENCIES
46
61
  mocha
47
62
  nokogiri
48
63
  rake
49
- rubocop (~> 0.67)
64
+ rubocop (>= 1.12.0)
50
65
  rubocop-performance
51
66
  simplecov
52
67
 
53
68
  BUNDLED WITH
54
- 1.17.3
69
+ 2.6.9
@@ -12,7 +12,7 @@ module OhlohScm
12
12
  end
13
13
 
14
14
  def log_filename
15
- File.join(temp_folder, url.gsub(/\W/, '') + '.log')
15
+ File.join(temp_folder, "#{url.gsub(/\W/, '')}.log")
16
16
  end
17
17
 
18
18
  def tags; end
@@ -29,7 +29,7 @@ module OhlohScm
29
29
  # Unlike other SCMs, Bzr doesn't simply place the contents into dest_dir.
30
30
  # It actually *creates* dest_dir. Since it should already exist at this point,
31
31
  # first we have to delete it.
32
- Dir.delete(dest_dir) if File.exist?(dest_dir)
32
+ FileUtils.rm_f(dest_dir)
33
33
 
34
34
  run "cd '#{url}' && bzr export --format=dir -r #{to_rev_param(token)} '#{dest_dir}'"
35
35
  end
@@ -45,7 +45,7 @@ module OhlohScm
45
45
  a = OhlohScm::BzrXmlParser.parse(log)
46
46
 
47
47
  if after && (i = a.index { |commit| commit.token == after })
48
- a[(i + 1)..-1]
48
+ a[(i + 1)..]
49
49
  else
50
50
  a
51
51
  end
@@ -74,8 +74,8 @@ module OhlohScm
74
74
  end
75
75
 
76
76
  def head_token
77
- run("bzr log --limit 1 --show-id #{url} 2> /dev/null"\
78
- " | grep ^revision-id | cut -f2 -d' '").strip
77
+ run("bzr log --limit 1 --show-id #{url} 2> /dev/null " \
78
+ "| grep ^revision-id | cut -f2 -d' '").strip
79
79
  end
80
80
 
81
81
  def head
@@ -136,24 +136,24 @@ module OhlohScm
136
136
  # +after+. However, bzr doesn't work that way; it returns
137
137
  # everything after and INCLUDING +after+. Therefore, consumers
138
138
  # of this file should check for and reject the duplicate commit.
139
- def safe_open_log_file(opts = {})
139
+ def safe_open_log_file(opts = {}, &block)
140
140
  return '' if opts[:after] && opts[:after] == head_token
141
141
 
142
- open_log_file(opts) { |io| yield io }
142
+ open_log_file(opts, &block)
143
143
  end
144
144
 
145
- def open_log_file(opts = {})
145
+ def open_log_file(opts = {}, &block)
146
146
  cmd = "#{rev_list_command(opts)} -v > #{log_filename}"
147
147
  run cmd
148
- File.open(log_filename, 'r') { |io| yield io }
148
+ File.open(log_filename, 'r', &block)
149
149
  ensure
150
- File.delete(log_filename) if File.exist?(log_filename)
150
+ FileUtils.rm_f(log_filename)
151
151
  end
152
152
 
153
153
  # Ohloh tracks only files, not directories. This function removes directories
154
154
  # from the commit diffs.
155
155
  def remove_directories(commit)
156
- commit.diffs.delete_if { |d| d.path[-1..-1] == '/' }
156
+ commit.diffs.delete_if { |d| d.path[-1..] == '/' }
157
157
  commit
158
158
  end
159
159
 
@@ -164,11 +164,11 @@ module OhlohScm
164
164
  # Bzr doesn't like it when the filename includes a colon
165
165
  # Also, fix the case where the filename includes a single quote
166
166
  def escape(path)
167
- path.gsub(/[:]/) { |c| '\\' + c }.gsub("'", "''")
167
+ path.gsub(':') { |c| "\\#{c}" }.gsub("'", "''")
168
168
  end
169
169
 
170
170
  def tag_strings
171
- run("cd '#{url}' && bzr tags").split(/\n/)
171
+ run("cd '#{url}' && bzr tags").split("\n")
172
172
  end
173
173
 
174
174
  def time_string(rev)
@@ -11,7 +11,7 @@ module OhlohScm
11
11
  end
12
12
 
13
13
  def public_url_regex
14
- %r{^(((http|https|bzr)://(\w+@)?[\w\-\.]+(:\d+)?/)|(lp:[\w\-\.\~]))[\w\-\./\~\+]*$}
14
+ %r{^(((http|https|bzr)://(\w+@)?[\w\-.]+(:\d+)?/)|(lp:[\w\-.~]))[\w\-./~+]*$}
15
15
  end
16
16
  end
17
17
  end
@@ -24,9 +24,7 @@ module OhlohScm
24
24
  attr_accessor :author_name, :author_email, :author_date,
25
25
  :committer_name, :committer_email, :committer_date
26
26
 
27
- attr_accessor :message
28
-
29
- attr_accessor :diffs
27
+ attr_accessor :message, :diffs
30
28
 
31
29
  # The token is used to uniquely identify a commit, and can be any type of
32
30
  # adapter-specific data.
@@ -46,7 +44,7 @@ module OhlohScm
46
44
  attr_accessor :directories
47
45
 
48
46
  def initialize(params = {})
49
- params.each { |k, v| send(k.to_s + '=', v) if respond_to?(k.to_s + '=') }
47
+ params.each { |k, v| send("#{k}=", v) if respond_to?("#{k}=") }
50
48
  end
51
49
  end
52
50
  end
@@ -11,9 +11,10 @@ module OhlohScm
11
11
  def initialize(scm_type, url, branch_name, username, password)
12
12
  scm_opts = { core: self, url: url, branch_name: branch_name,
13
13
  username: username, password: password }
14
+
14
15
  scm_class_name = scm_type.to_s.camelize
15
16
 
16
- @scm = OhlohScm.const_get(scm_class_name)::Scm.new(scm_opts)
17
+ @scm = OhlohScm.const_get(scm_class_name)::Scm.new(**scm_opts)
17
18
  @activity = OhlohScm.const_get(scm_class_name)::Activity.new(self)
18
19
  @status = OhlohScm.const_get(scm_class_name)::Status.new(self)
19
20
  @validation = OhlohScm.const_get(scm_class_name)::Validation.new(self)
@@ -5,79 +5,95 @@ module OhlohScm
5
5
  class Activity < OhlohScm::Activity
6
6
  def tags
7
7
  cmd = "cvs -Q -d #{url} rlog -h #{scm.branch_name} | awk -F\"[.:]\" '/^\\t/&&$(NF-1)!=0'"
8
- tag_strings = run(cmd).split(/\n/)
9
- tag_strings.map do |tag_string|
8
+ run(cmd).split("\n").map do |tag_string|
10
9
  tag_name, version = tag_string.split(':')
11
10
  [tag_name.delete("\t"), version.strip]
12
11
  end
13
12
  end
14
13
 
15
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
16
14
  def commits(opts = {})
17
- after = opts[:after]
18
- result = []
15
+ result = fetch_commits(opts)
16
+ # Nothing found; we're done here. || We requested everything, so just return everything.
17
+ return result if result.empty? || opts[:after].to_s.empty?
19
18
 
20
- open_log_file(opts) do |io|
21
- result = OhlohScm::CvsParser.parse(io)
22
- end
19
+ filter_commits(result, opts[:after])
20
+ end
23
21
 
24
- # Git converter needs a backpointer to the scm for each commit
25
- result.each { |c| c.scm = scm }
22
+ def export_tag(dest_dir, tag_name = 'HEAD')
23
+ run "cvsnt -d #{url} export -d'#{dest_dir}' -r #{tag_name} '#{scm.branch_name}'"
24
+ end
26
25
 
27
- return result if result.empty? # Nothing found; we're done here.
28
- return result if after.to_s == '' # We requested everything, so just return everything.
26
+ # using :ext (ssh) protocol might trigger ssh to confirm accepting the host's
27
+ # ssh key. This causes the UI to hang asking for manual confirmation. To avoid
28
+ # this we pre-populate the ~/.ssh/known_hosts file with the host's key.
29
+ def ensure_host_key
30
+ return if protocol != :ext
29
31
 
30
- # We must now remove any duplicates caused by timestamp fudge factors,
31
- # and only return commits with timestamp > after.
32
+ ensure_key_file = "#{File.dirname(__FILE__)}/../../../../bin/ensure_key"
33
+ cmd = "#{ensure_key_file} '#{host}'"
34
+ run_with_err(cmd)
35
+ end
32
36
 
33
- # If the first commit is newer than after,
34
- # then the whole list is new and we can simply return.
35
- return result if parse_time(result.first.token) > parse_time(after)
37
+ private
38
+
39
+ def fetch_commits(opts)
40
+ OhlohScm::CvsParser.parse(open_log_file(opts)).tap do |result|
41
+ # Git converter needs a backpointer to the scm for each commit
42
+ result.each { |c| c.scm = scm }
43
+ end
44
+ end
45
+
46
+ def filter_commits(commits, after)
47
+ return commits if first_commit_newer?(commits, after)
36
48
 
37
49
  # Walk the list of commits to find the first new one, throwing away all of the old ones.
38
50
 
39
51
  # I want to string-compare timestamps without converting to dates objects.
40
52
  # Some CVS servers print dates as 2006/01/02 03:04:05, others as 2006-01-02 03:04:05.
41
53
  # To work around this, we'll build a regex that matches either date format.
42
- re = Regexp.new(after.gsub(/[\/-]/, '.'))
54
+ timestamp_regex = create_timestamp_regex(after)
55
+ match_index = find_match_index(commits, timestamp_regex)
43
56
 
44
- result.each_index do |i|
45
- next unless result[i].token&.match?(re) # We found the match for after
46
- return [] if i == result.size - 1 # There aren't any new commits.
57
+ extract_new_commits(commits, match_index)
58
+ end
47
59
 
48
- return result[i + 1..-1]
49
- end
60
+ def first_commit_newer?(commits, after)
61
+ # We must now remove any duplicates caused by timestamp fudge factors,
62
+ # and only return commits with timestamp > after.
50
63
 
51
- # Something bad is going on: 'after' does not match any timestamp in the rlog.
52
- # This is very rare, but it can happen.
53
- #
54
- # Often this means that the *last* time we ran commits(), there was some kind of
55
- # undetected problem (CVS was in an intermediate state?) so the list of timestamps we
56
- # calculated last time does not match the list of timestamps we calculated this time.
57
- #
58
- # There's no work around for this condition here in the code, but there are some things
59
- # you can try manually to fix the problem. Typically, you can try throwing way the
60
- # commit associated with 'after' and fetching it again (git reset --hard HEAD^).
61
- raise "token '#{after}' not found in rlog."
64
+ # If the first commit is newer than after,
65
+ # then the whole list is new and we can simply return.
66
+ parse_time(commits.first.token) > parse_time(after)
62
67
  end
63
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
64
68
 
65
- def export_tag(dest_dir, tag_name = 'HEAD')
66
- run "cvsnt -d #{url} export -d'#{dest_dir}' -r #{tag_name} '#{scm.branch_name}'"
69
+ def create_timestamp_regex(timestamp)
70
+ Regexp.new(timestamp.gsub(/[\/-]/, '.'))
67
71
  end
68
72
 
69
- # using :ext (ssh) protocol might trigger ssh to confirm accepting the host's
70
- # ssh key. This causes the UI to hang asking for manual confirmation. To avoid
71
- # this we pre-populate the ~/.ssh/known_hosts file with the host's key.
72
- def ensure_host_key
73
- return if protocol != :ext
74
-
75
- ensure_key_file = File.dirname(__FILE__) + '/../../../../bin/ensure_key'
76
- cmd = "#{ensure_key_file} '#{host}'"
77
- run_with_err(cmd)
73
+ def find_match_index(commits, timestamp_regex)
74
+ commits.index { |commit| commit.token&.match?(timestamp_regex) }
78
75
  end
79
76
 
80
- private
77
+ def extract_new_commits(commits, match_index)
78
+ case match_index
79
+ when nil
80
+ # Something bad is going on: 'after' does not match any timestamp in the rlog.
81
+ # This is very rare, but it can happen.
82
+ #
83
+ # Often this means that the *last* time we ran commits(), there was some kind of
84
+ # undetected problem (CVS was in an intermediate state?) so the list of timestamps we
85
+ # calculated last time does not match the list of timestamps we calculated this time.
86
+ #
87
+ # There's no work around for this condition here in the code, but there are some things
88
+ # you can try manually to fix the problem. Typically, you can try throwing way the
89
+ # commit associated with 'after' and fetching it again (git reset --hard HEAD^).
90
+ raise 'token not found in rlog.'
91
+ when commits.size - 1
92
+ []
93
+ else
94
+ commits[match_index + 1..]
95
+ end
96
+ end
81
97
 
82
98
  # Gets the rlog of the repository and saves it in a temporary file.
83
99
  # If you pass a timestamp token, then only commits after the timestamp will be returned.
@@ -91,29 +107,27 @@ module OhlohScm
91
107
  # This means that the returned log might actually contain a few revisions
92
108
  # that predate the requested time.
93
109
  # That's better than missing revisions completely! Just be sure to check for duplicates.
94
- # rubocop:disable Metrics/AbcSize
95
- def open_log_file(opts = {})
110
+ def open_log_file(opts = {}, &block)
96
111
  ensure_host_key
97
112
  status.lock?
98
- run "cvsnt -d #{url} rlog #{opt_branch} #{opt_time(opts[:after])} '#{scm.branch_name}'"\
99
- " | #{string_encoder_path} > #{rlog_filename}"
100
- File.open(rlog_filename, 'r') { |file| yield file }
113
+ run "cvsnt -d #{url} rlog #{opt_branch} #{opt_time(opts[:after])} '#{scm.branch_name}' " \
114
+ "| #{string_encoder_path} > #{rlog_filename}"
115
+ File.open(rlog_filename, 'r', &block)
101
116
  ensure
102
- File.delete(rlog_filename) if File.exist?(rlog_filename)
117
+ FileUtils.rm_f(rlog_filename)
103
118
  end
104
- # rubocop:enable Metrics/AbcSize
105
119
 
106
120
  def opt_time(after = nil)
107
121
  return '' unless after
108
122
 
109
123
  most_recent_time = parse_time(after) - 10
110
- # rubocop:disable Metrics/LineLength
124
+ # rubocop:disable Layout/LineLength
111
125
  " -d '#{most_recent_time.strftime('%Y-%m-%d %H:%M:%S')}Z<#{Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')}Z' "
112
- # rubocop:enable Metrics/LineLength
126
+ # rubocop:enable Layout/LineLength
113
127
  end
114
128
 
115
129
  def rlog_filename
116
- File.join(temp_folder, (url + scm.branch_name.to_s).gsub(/\W/, '') + '.rlog')
130
+ File.join(temp_folder, "#{(url + scm.branch_name.to_s).gsub(/\W/, '')}.rlog")
117
131
  end
118
132
 
119
133
  # Converts a CVS time string to a Ruby Time object
@@ -128,9 +142,9 @@ module OhlohScm
128
142
  # returns the host this adapter is connecting to
129
143
  def host
130
144
  @host ||= begin
131
- url =~ /@([^:]*):/
132
- Regexp.last_match(1)
133
- end
145
+ url =~ /@([^:]*):/
146
+ Regexp.last_match(1)
147
+ end
134
148
  end
135
149
 
136
150
  # returns the protocol this adapter connects with
@@ -9,9 +9,14 @@ module OhlohScm
9
9
  opt_d = rev.token ? "-D'#{rev.token}Z'" : ''
10
10
 
11
11
  activity.ensure_host_key
12
- if File.exist?(local_directory + '/CVS/Root')
12
+ if File.exist?("#{local_directory}/CVS/Root")
13
13
  # We already have a local enlistment, so do a quick update.
14
- if !rev.directories.empty?
14
+ if rev.directories.empty?
15
+ # Brute force: get all updates
16
+ logger.warn("Revision #{rev.token} did not contain any directories.
17
+ Using brute force update of entire module.")
18
+ run "cd #{local_directory} && cvsnt update -d -R -C #{opt_d}"
19
+ else
15
20
  build_ordered_directory_list(rev.directories).each do |d|
16
21
  if d.empty?
17
22
  run "cd #{local_directory} && cvsnt update -d -l -C #{opt_d} ."
@@ -19,18 +24,13 @@ module OhlohScm
19
24
  run "cd #{local_directory} && cvsnt update -d -l -C #{opt_d} '#{d}'"
20
25
  end
21
26
  end
22
- else
23
- # Brute force: get all updates
24
- logger.warn("Revision #{rev.token} did not contain any directories.
25
- Using brute force update of entire module.")
26
- run "cd #{local_directory} && cvsnt update -d -R -C #{opt_d}"
27
27
  end
28
28
  else
29
29
  # We do not have a local enlistment, so do a slow checkout to create one.
30
30
  # Silly cvsnt won't accept an absolute path.
31
31
  # We'll have to play some games and cd to the parent directory.
32
32
  parent_path, checkout_dir = File.split(local_directory)
33
- FileUtils.mkdir_p(parent_path) unless File.exist?(parent_path)
33
+ FileUtils.mkdir_p(parent_path)
34
34
  run "cd #{parent_path} &&
35
35
  cvsnt -d #{url} checkout #{opt_d} -A -d'#{checkout_dir}' '#{branch_name}'"
36
36
  end
@@ -66,7 +66,7 @@ module OhlohScm
66
66
  # using cvs modules that are only a single directory deep when testing.
67
67
  # We'll check if the url begins with '/' to detect an integration test,
68
68
  # then return an empty string (ie, the default root directory) if so.
69
- return [''] if url =~ /^\//
69
+ return [''] if /^\//.match?(url)
70
70
 
71
71
  list = []
72
72
  directories = directories.collect { |a| trim_directory(a.to_s).to_s }
@@ -105,7 +105,7 @@ module OhlohScm
105
105
  # For example, if url = ':pserver:anonymous:@moodle.cvs.sourceforge.net:/cvsroot/moodle'
106
106
  # and module = 'contrib', then the directory prefix = '/cvsroot/moodle/contrib/'
107
107
  # If not remote, just leave the directory name as-is
108
- root ? dir[root.length..-1] : dir
108
+ root ? dir[root.length..] : dir
109
109
  end
110
110
 
111
111
  def root
@@ -126,7 +126,7 @@ module OhlohScm
126
126
  # found in the :pserver: url is assigned to both.
127
127
  def sync_pserver_username_password
128
128
  # Do nothing unless pserver connection string is well-formed.
129
- return unless url =~ /:pserver:([\w\-\_]*)(:([\w\-\_]*))?@(.*)$/
129
+ return unless url =~ /:pserver:([\w\-_]*)(:([\w\-_]*))?@(.*)$/
130
130
 
131
131
  pserver_username = Regexp.last_match(1)
132
132
  pserver_password = Regexp.last_match(3)
@@ -140,7 +140,7 @@ module OhlohScm
140
140
 
141
141
  # Based on the URL, take a guess about which forge this code is hosted on.
142
142
  def guess_forge
143
- return unless url =~ /.*(pserver|ext).*@(([^\.]+\.)?(cvs|dev)\.)?([^:]+):\//i
143
+ return unless url =~ /.*(pserver|ext).*@(([^.]+\.)?(cvs|dev)\.)?([^:]+):\//i
144
144
 
145
145
  Regexp.last_match(5).downcase
146
146
  end
@@ -7,7 +7,7 @@ module OhlohScm
7
7
  run "timeout 2m cvsnt -q -d #{scm.url} rlog '#{scm.branch_name}'"
8
8
  false
9
9
  rescue StandardError => e
10
- raise 'CVS lock has been found' if e.message =~ /waiting for.*lock in/
10
+ raise 'CVS lock has been found' if /waiting for.*lock in/.match?(e.message)
11
11
  end
12
12
  end
13
13
  end
@@ -19,14 +19,14 @@ module OhlohScm
19
19
  [:branch_name, "The branch name can't be blank."]
20
20
  elsif scm.branch_name.length > 200
21
21
  [:branch_name, 'The branch name must not be longer than 200 characters.']
22
- elsif !scm.branch_name.match?(/^[\w\-\+\.\/\ ]+$/)
22
+ elsif !scm.branch_name.match?(/^[\w\-+.\/\ ]+$/)
23
23
  [:branch_name, "The branch name may contain only letters,
24
24
  numbers, spaces, and the special characters '_', '-', '+', '/', and '.'"]
25
25
  end
26
26
  end
27
27
 
28
28
  def public_url_regex
29
- /^:(pserver|ext):[\w\-\+\_]*(:[\w\-\+\_]*)?@[\w\-\+\.]+:[0-9]*\/[\w\-\+\.\/]*$/
29
+ /^:(pserver|ext):[\w\-+_]*(:[\w\-+_]*)?@[\w\-+.]+:[0-9]*\/[\w\-+.\/]*$/
30
30
  end
31
31
 
32
32
  # Returns an array of file and directory names from the remote server.
@@ -56,7 +56,7 @@ module OhlohScm
56
56
  files = []
57
57
  output.each_line do |s|
58
58
  s.strip!
59
- s = Regexp.last_match(1) + '/' if s =~ /^D\/(.*)\/\/\/\/$/
59
+ s = "#{Regexp.last_match(1)}/" if s =~ /^D\/(.*)\/\/\/\/$/
60
60
  s = Regexp.last_match(1) if s =~ /^\/(.*)\/.*\/.*\/.*\/$/
61
61
  next if s == 'CVSROOT/'
62
62
 
@@ -34,7 +34,7 @@ module OhlohScm
34
34
  attr_accessor :from_path, :from_revision
35
35
 
36
36
  def initialize(params = {})
37
- params.each { |k, v| send(k.to_s + '=', v) if respond_to?(k.to_s + '=') }
37
+ params.each { |k, v| send("#{k}=", v) if respond_to?("#{k}=") }
38
38
  end
39
39
 
40
40
  # eql?() and hash() are implemented so that [].uniq() will work on an array of Diffs.
@@ -4,7 +4,13 @@ module OhlohScm
4
4
  module Factory
5
5
  module_function
6
6
 
7
- def get_core(scm_type: :git, url:, branch_name: nil, username: nil, password: nil)
7
+ def get_core(opts = {})
8
+ scm_type = opts.fetch(:scm_type, :git)
9
+ url = opts.fetch(:url) { raise ArgumentError, 'URL is required' }
10
+ branch_name = opts[:branch_name]
11
+ username = opts[:username]
12
+ password = opts[:password]
13
+
8
14
  OhlohScm::Core.new(scm_type, url, branch_name, username, password)
9
15
  end
10
16
  end