capistrano-git-copy 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07c610ece9909effffdeee0113bf361c64c88039fafff39564e9a2742e862d8c
4
- data.tar.gz: 90046d84e5b763fc5bf6c947433813934c12f9e16c86b4a082883ab6f89c1fec
3
+ metadata.gz: '0193555dcc7eefb6ad1c129cc92d99314fd5631a386f8daf39e4ef53a5ab9d7d'
4
+ data.tar.gz: 60b392776e795ee02a8cf2af8c4952c8d33eceb9277a2fd7c782e67b01189da3
5
5
  SHA512:
6
- metadata.gz: 91c2cc32118c9ac4fbe1d941c3c9bfd1b60d63e98b68bb487abc2171e58582cc218a39c0893b21e591b7e41c12ded879e431abe2d85a1c848aa0547b94e43b48
7
- data.tar.gz: 62ac5254df68295657e40ba341a2a4eee4d6a3be37e38bfa5f58f8996c5d70cd2042cefc173198435a38bd941c64c6b4b4204ffec67d644289a9b817360fe975
6
+ metadata.gz: e125d7493ca8d54242e211604105b5d138e5c1944a165efdd888fde77599204a40ca47dcd9b5ea4ba16d765b6c2af9fdcc2f8cc5bd93435fb3c8158f5f827282
7
+ data.tar.gz: d5627c293b8a6cf4b614dae2b86779468eb0fd48baa43ea9ad43ff745bc5437a994785f02575221549c1e9b6627ccad340c7abf65c38b875ff5d084973b19c9d
@@ -0,0 +1,5 @@
1
+ rubocop:
2
+ image: ruby:2.5
3
+ script:
4
+ - gem install rubocop --no-ri --no-rdoc
5
+ - rubocop
@@ -1,3 +1,3 @@
1
1
  [submodule "vendor/git-archive-all"]
2
2
  path = vendor/git-archive-all
3
- url = https://github.com/ydkn/git-archive-all.git
3
+ url = https://gitlab.com/ydkn/git-archive-all.git
@@ -0,0 +1,5 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+
4
+ Metrics/BlockLength:
5
+ Max: 100
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 1.5.1 (2018-09-24)
4
+ ### Changes
5
+ - updated _git-archive-all_ to 1.18.2
6
+
3
7
  ## 1.5.0 (2018-05-24)
4
8
  ### Feature
5
9
  - add option to switch off running git clean (#25)
data/README.md CHANGED
@@ -1,10 +1,3 @@
1
- [![Gem Version](https://img.shields.io/gem/v/capistrano-git-copy.svg)](https://rubygems.org/gems/capistrano-git-copy)
2
- [![Dependencies](https://img.shields.io/gemnasium/ydkn/capistrano-git-copy.svg)](https://gemnasium.com/ydkn/capistrano-git-copy)
3
- [![Code Climate](https://img.shields.io/codeclimate/github/ydkn/capistrano-git-copy.svg)](https://codeclimate.com/github/ydkn/capistrano-git-copy)
4
-
5
- [![Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ydkn/capistrano-git-copy)
6
-
7
-
8
1
  # Capistrano::GitCopy
9
2
 
10
3
  Creates a tar archive locally from the git repository and uploads it to the remote server.
@@ -1,5 +1,4 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'capistrano/git_copy/version'
5
4
 
@@ -10,17 +9,17 @@ Gem::Specification.new do |spec|
10
9
  spec.email = ['me@ydkn.de']
11
10
  spec.description = 'Copy local git repository deploy strategy for capistrano.'
12
11
  spec.summary = 'Copy local git repository deploy strategy for capistrano.'
13
- spec.homepage = 'https://github.com/ydkn/capistrano-git-copy'
12
+ spec.homepage = 'https://gitlab.com/ydkn/capistrano-git-copy'
14
13
  spec.license = 'MIT'
15
14
 
16
- spec.files = `git ls-files`.split($/) + %w( vendor/git-archive-all/git_archive_all.py )
15
+ spec.files = `git ls-files`.split("\n") + %w[vendor/git-archive-all/git_archive_all.py]
17
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ['lib']
20
19
 
21
20
  spec.add_dependency 'capistrano', '>= 3.7.0', '< 4.0.0'
22
21
 
23
- spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'bundler'
24
23
  spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'yard'
24
+ spec.add_development_dependency 'rubocop'
26
25
  end
@@ -1,11 +1,14 @@
1
1
  require 'tmpdir'
2
2
  require 'capistrano/scm/plugin'
3
+ require 'capistrano/git_copy/scm_helpers'
3
4
 
4
5
  module Capistrano
5
6
  module GitCopy
6
7
  # SCM plugin for capistrano
7
8
  # uses a local clone and uploads a tar archive to the server
8
9
  class SCM < ::Capistrano::SCM::Plugin
10
+ include Capistrano::GitCopy::SCMHelpers
11
+
9
12
  # set default values
10
13
  def set_defaults
11
14
  set_if_empty :with_clean, true
@@ -16,7 +19,7 @@ module Capistrano
16
19
 
17
20
  # define plugin tasks
18
21
  def define_tasks
19
- eval_rakefile File.expand_path('../tasks/git_copy.rake', __FILE__)
22
+ eval_rakefile File.expand_path('tasks/git_copy.rake', __dir__)
20
23
  end
21
24
 
22
25
  # register capistrano hooks
@@ -38,15 +41,7 @@ module Capistrano
38
41
  # @return [Boolean] indicates if repo cache exists
39
42
  def test
40
43
  if backend.test("[ -d #{repo_cache_path} ]")
41
- backend.within(repo_cache_path) do
42
- if backend.test(:git, :status, '>/dev/null 2>/dev/null')
43
- true
44
- else
45
- backend.execute(:rm, '-rf', repo_cache_path)
46
-
47
- false
48
- end
49
- end
44
+ check_repo_cache_path
50
45
  else
51
46
  false
52
47
  end
@@ -76,26 +71,16 @@ module Capistrano
76
71
  end
77
72
 
78
73
  # cleanup
79
- if fetch(:with_clean)
80
- git(:clean, '-d', '-f')
81
- end
74
+ git(:clean, '-d', '-f') if fetch(:with_clean)
82
75
 
83
- if fetch(:with_submodules)
84
- git(:submodule, :foreach, '--recursive', :git, :clean, '-d', '-f')
85
- end
76
+ git(:submodule, :foreach, '--recursive', :git, :clean, '-d', '-f') if fetch(:with_submodules)
86
77
  end
87
78
 
88
79
  # Create tar archive
89
80
  #
90
81
  # @return void
91
82
  def prepare_release
92
- if fetch(:upload_path) != '.'
93
- backend.execute(:tar, '-czf', archive_path, '-C', fetch(:upload_path), '.')
94
- elsif fetch(:with_submodules)
95
- backend.execute(git_archive_all_bin, "--prefix=''", archive_path)
96
- else
97
- git(:archive, '--format=tar', 'HEAD', '|', 'gzip', "> #{archive_path}")
98
- end
83
+ package_release_archive
99
84
 
100
85
  exclude_files_from_archive if fetch(:git_excludes, []).count > 0
101
86
  end
@@ -110,9 +95,7 @@ module Capistrano
110
95
 
111
96
  backend.upload!(archive_path, remote_archive_path)
112
97
 
113
- backend.execute(:mkdir, '-p', release_path)
114
- backend.execute(:tar, '-f', remote_archive_path, '-x', '-C', release_path)
115
- backend.execute(:rm, '-f', remote_archive_path)
98
+ extract_archive_on_remote(remote_archive_path)
116
99
  end
117
100
 
118
101
  # Set deployed revision
@@ -135,74 +118,21 @@ module Capistrano
135
118
  #
136
119
  # @return [String]
137
120
  def tmp_path
138
- @_tmp_path ||= File.join(Dir.tmpdir, deploy_id)
121
+ @tmp_path ||= File.join(Dir.tmpdir, deploy_id)
139
122
  end
140
123
 
141
124
  # Path to repository cache
142
125
  #
143
126
  # @return [String]
144
127
  def repo_cache_path
145
- @_repo_cache_path ||= fetch(:git_repo_cach_path, File.join(tmp_path, 'repo'))
128
+ @repo_cache_path ||= fetch(:git_repo_cach_path, File.join(tmp_path, 'repo'))
146
129
  end
147
130
 
148
131
  # Path to archive
149
132
  #
150
133
  # @return [String]
151
134
  def archive_path
152
- @_archive_path ||= File.join(tmp_path, 'archive.tar.gz')
153
- end
154
-
155
- private
156
-
157
- def deploy_id
158
- [
159
- fetch(:application),
160
- fetch(:stage),
161
- Digest::MD5.hexdigest(fetch(:repo_url))[0..7],
162
- Digest::MD5.hexdigest(Dir.getwd)[0..7]
163
- ].compact.join('_').gsub(/[^\w]/, '')
164
- end
165
-
166
- def commit_hash
167
- return @_commit_hash if @_commit_hash
168
-
169
- branch = fetch(:branch, 'master').to_s.strip
170
-
171
- if backend.test(:git, 'rev-parse', "origin/#{branch}", '>/dev/null 2>/dev/null')
172
- @_commit_hash = backend.capture(:git, 'rev-parse', "origin/#{branch}").strip
173
- else
174
- @_commit_hash = backend.capture(:git, 'rev-parse', branch).strip
175
- end
176
- end
177
-
178
- def git_archive_all_bin
179
- File.expand_path('../../../../vendor/git-archive-all/git_archive_all.py', __FILE__)
180
- end
181
-
182
- def git(*args)
183
- backend.execute(:git, *args)
184
- end
185
-
186
- def exclude_files_from_archive
187
- archive_dir = File.join(tmp_path, 'archive')
188
-
189
- backend.execute(:rm, '-rf', archive_dir)
190
- backend.execute(:mkdir, '-p', archive_dir)
191
- backend.execute(:tar, '-xzf', archive_path, '-C', archive_dir)
192
-
193
- fetch(:git_excludes, []).each do |f|
194
- file_path = File.join(archive_dir, f.gsub(/\A\//, ''))
195
-
196
- unless File.exists?(file_path)
197
- backend.warn("#{f} does not exists!")
198
-
199
- next
200
- end
201
-
202
- FileUtils.rm_rf(file_path)
203
- end
204
-
205
- backend.execute(:tar, '-czf', archive_path, '-C', archive_dir, '.')
135
+ @archive_path ||= File.join(tmp_path, 'archive.tar.gz')
206
136
  end
207
137
  end
208
138
  end
@@ -0,0 +1,93 @@
1
+ require 'tmpdir'
2
+
3
+ module Capistrano
4
+ module GitCopy
5
+ # Helper methods for capistrano SCM plugin
6
+ module SCMHelpers
7
+ private
8
+
9
+ def deploy_id
10
+ [
11
+ fetch(:application),
12
+ fetch(:stage),
13
+ Digest::MD5.hexdigest(fetch(:repo_url))[0..7],
14
+ Digest::MD5.hexdigest(Dir.getwd)[0..7]
15
+ ].compact.join('_').gsub(/[^\w]/, '')
16
+ end
17
+
18
+ def commit_hash
19
+ return @commit_hash if @commit_hash
20
+
21
+ branch = fetch(:branch, 'master').to_s.strip
22
+
23
+ @commit_hash = if backend.test(:git, 'rev-parse', "origin/#{branch}", '>/dev/null 2>/dev/null')
24
+ backend.capture(:git, 'rev-parse', "origin/#{branch}").strip
25
+ else
26
+ backend.capture(:git, 'rev-parse', branch).strip
27
+ end
28
+ end
29
+
30
+ def git_archive_all_bin
31
+ File.expand_path('../../../vendor/git-archive-all/git_archive_all.py', __dir__)
32
+ end
33
+
34
+ def git(*args)
35
+ backend.execute(:git, *args)
36
+ end
37
+
38
+ def check_repo_cache_path
39
+ backend.within(repo_cache_path) do
40
+ if backend.test(:git, :status, '>/dev/null 2>/dev/null')
41
+ true
42
+ else
43
+ backend.execute(:rm, '-rf', repo_cache_path)
44
+
45
+ false
46
+ end
47
+ end
48
+ end
49
+
50
+ def package_release_archive
51
+ if fetch(:upload_path) != '.'
52
+ backend.execute(:tar, '-czf', archive_path, '-C', fetch(:upload_path), '.')
53
+ elsif fetch(:with_submodules)
54
+ backend.execute(git_archive_all_bin, "--prefix=''", archive_path)
55
+ else
56
+ git(:archive, '--format=tar', 'HEAD', '|', 'gzip', "> #{archive_path}")
57
+ end
58
+ end
59
+
60
+ def exclude_files_from_archive
61
+ archive_dir = File.join(tmp_path, 'archive')
62
+
63
+ backend.execute(:rm, '-rf', archive_dir)
64
+ backend.execute(:mkdir, '-p', archive_dir)
65
+ backend.execute(:tar, '-xzf', archive_path, '-C', archive_dir)
66
+
67
+ remove_file_from_archive_dir(archive_dir)
68
+
69
+ backend.execute(:tar, '-czf', archive_path, '-C', archive_dir, '.')
70
+ end
71
+
72
+ def remove_file_from_archive_dir(archive_dir)
73
+ fetch(:git_excludes, []).each do |f|
74
+ file_path = File.join(archive_dir, f.gsub(%r{\A/}, ''))
75
+
76
+ unless File.exist?(file_path)
77
+ backend.warn("#{f} does not exists!")
78
+
79
+ next
80
+ end
81
+
82
+ FileUtils.rm_rf(file_path)
83
+ end
84
+ end
85
+
86
+ def extract_archive_on_remote(remote_archive_path)
87
+ backend.execute(:mkdir, '-p', release_path)
88
+ backend.execute(:tar, '-f', remote_archive_path, '-x', '-C', release_path)
89
+ backend.execute(:rm, '-f', remote_archive_path)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -3,6 +3,6 @@ module Capistrano
3
3
  # GitCopy
4
4
  module GitCopy
5
5
  # gem version
6
- VERSION = '1.5.0'
6
+ VERSION = '1.5.1'.freeze
7
7
  end
8
8
  end
@@ -27,14 +27,29 @@ from __future__ import print_function
27
27
  from __future__ import unicode_literals
28
28
 
29
29
  import logging
30
- from os import extsep, path, readlink, curdir
30
+ from os import extsep, path, readlink
31
31
  from subprocess import CalledProcessError, Popen, PIPE
32
32
  import sys
33
- import tarfile
34
- from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
35
33
  import re
36
34
 
37
- __version__ = "1.17.1"
35
+ __version__ = "1.18.2"
36
+
37
+
38
+ try:
39
+ # Python 3.3+
40
+ from shlex import quote
41
+ except ImportError:
42
+ _find_unsafe = re.compile(r'[^a-zA-Z0-9_@%+=:,./-]').search
43
+
44
+ def quote(s):
45
+ """Return a shell-escaped version of the string *s*."""
46
+ if not s:
47
+ return "''"
48
+
49
+ if _find_unsafe(s) is None:
50
+ return s
51
+
52
+ return "'" + s.replace("'", "'\"'\"'") + "'"
38
53
 
39
54
 
40
55
  class GitArchiver(object):
@@ -48,6 +63,17 @@ class GitArchiver(object):
48
63
  >>> archiver = GitArchiver(main_repo_abspath='my/repo/path')
49
64
  >>> archiver.create('output.zip')
50
65
  """
66
+ TARFILE_FORMATS = {
67
+ 'tar': 'w',
68
+ 'tbz2': 'w:bz2',
69
+ 'tgz': 'w:gz',
70
+ 'txz': 'w:xz',
71
+ 'bz2': 'w:bz2',
72
+ 'gz': 'w:gz',
73
+ 'xz': 'w:xz'
74
+ }
75
+ ZIPFILE_FORMATS = ('.zip',)
76
+
51
77
  LOG = logging.getLogger('GitArchiver')
52
78
 
53
79
  def __init__(self, prefix='', exclude=True, force_sub=False, extra=None, main_repo_abspath=None):
@@ -118,7 +144,9 @@ class GitArchiver(object):
118
144
  self.LOG.debug("Output format is not explicitly set, determined format is {0}.".format(output_format))
119
145
 
120
146
  if not dry_run:
121
- if output_format == 'zip':
147
+ if output_format in self.ZIPFILE_FORMATS:
148
+ from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED
149
+
122
150
  archive = ZipFile(path.abspath(output_path), 'w')
123
151
 
124
152
  def add_file(file_path, arcname):
@@ -129,25 +157,19 @@ class GitArchiver(object):
129
157
  i.create_system = 3
130
158
  i.external_attr = 0xA1ED0000
131
159
  archive.writestr(i, readlink(file_path))
132
- elif output_format in ['tar', 'bz2', 'gz', 'xz', 'tgz', 'txz']:
133
- if output_format == 'tar':
134
- t_mode = 'w'
135
- elif output_format == 'tgz':
136
- t_mode = 'w:gz'
137
- elif output_format == 'txz':
138
- t_mode = 'w:xz'
139
- else:
140
- t_mode = 'w:{0}'.format(output_format)
141
-
142
- archive = tarfile.open(path.abspath(output_path), t_mode)
160
+ elif output_format in self.TARFILE_FORMATS:
161
+ import tarfile
162
+
163
+ mode = self.TARFILE_FORMATS[output_format]
164
+ archive = tarfile.open(path.abspath(output_path), mode)
143
165
 
144
166
  def add_file(file_path, arcname):
145
167
  archive.add(file_path, arcname)
146
168
  else:
147
- raise RuntimeError("unknown format: {0}".format(output_format))
169
+ raise ValueError("unknown format: {0}".format(output_format))
148
170
 
149
171
  def archiver(file_path, arcname):
150
- self.LOG.debug("Compressing {0} => {1}...".format(file_path, arcname))
172
+ self.LOG.debug("{0} => {1}".format(file_path, arcname))
151
173
  add_file(file_path, arcname)
152
174
  else:
153
175
  archive = None
@@ -160,105 +182,28 @@ class GitArchiver(object):
160
182
  if archive is not None:
161
183
  archive.close()
162
184
 
163
- def get_exclude_patterns(self, repo_abspath, repo_file_paths):
164
- """
165
- Returns exclude patterns for a given repo. It looks for .gitattributes files in repo_file_paths.
166
-
167
- Resulting dictionary will contain exclude patterns per path (relative to the repo_abspath).
168
- E.g. {('.', 'Catalyst', 'Editions', 'Base'): ['Foo*', '*Bar']}
169
-
170
- @param repo_abspath: Absolute path to the git repository.
171
- @type repo_abspath: str
172
-
173
- @param repo_file_paths: List of paths relative to the repo_abspath that are under git control.
174
- @type repo_file_paths: list
175
-
176
- @return: Dictionary representing exclude patterns.
177
- Keys are tuples of strings. Values are lists of strings.
178
- Returns None if self.exclude is not set.
179
- @rtype: dict or None
180
- """
181
- if not self.exclude:
182
- return None
183
-
184
- def read_attributes(attributes_abspath):
185
- patterns = []
186
- if path.isfile(attributes_abspath):
187
- attributes = open(attributes_abspath, 'r').readlines()
188
- patterns = []
189
- for line in attributes:
190
- tokens = line.strip().split()
191
- if "export-ignore" in tokens[1:]:
192
- patterns.append(tokens[0])
193
- return patterns
194
-
195
- exclude_patterns = {(): []}
196
-
197
- # There may be no gitattributes.
198
- try:
199
- global_attributes_abspath = self.run_git_shell("git config --get core.attributesfile", repo_abspath).rstrip()
200
- exclude_patterns[()] = read_attributes(global_attributes_abspath)
201
- except:
202
- # And it's valid to not have them.
203
- pass
204
-
205
- for attributes_abspath in [path.join(repo_abspath, f) for f in repo_file_paths if f.endswith(".gitattributes")]:
206
- # Each .gitattributes affects only files within its directory.
207
- key = tuple(self.get_path_components(repo_abspath, path.dirname(attributes_abspath)))
208
- exclude_patterns[key] = read_attributes(attributes_abspath)
209
-
210
- local_attributes_abspath = path.join(repo_abspath, ".git", "info", "attributes")
211
- key = tuple(self.get_path_components(repo_abspath, repo_abspath))
212
-
213
- if key in exclude_patterns:
214
- exclude_patterns[key].extend(read_attributes(local_attributes_abspath))
215
- else:
216
- exclude_patterns[key] = read_attributes(local_attributes_abspath)
217
-
218
- return exclude_patterns
219
-
220
- def is_file_excluded(self, repo_abspath, repo_file_path, exclude_patterns):
185
+ def is_file_excluded(self, repo_abspath, repo_file_path):
221
186
  """
222
187
  Checks whether file at a given path is excluded.
223
188
 
224
189
  @param repo_abspath: Absolute path to the git repository.
225
190
  @type repo_abspath: str
226
191
 
227
- @param repo_file_path: Path to a file within repo_abspath.
192
+ @param repo_file_path: Path to a file relative to repo_abspath.
228
193
  @type repo_file_path: str
229
194
 
230
- @param exclude_patterns: Exclude patterns with format specified for get_exclude_patterns.
231
- @type exclude_patterns: dict
232
-
233
195
  @return: True if file should be excluded. Otherwise False.
234
196
  @rtype: bool
235
197
  """
236
- if exclude_patterns is None or not len(exclude_patterns):
237
- return False
198
+ out = self.run_git_shell(
199
+ 'git check-attr -z export-ignore -- %s' % quote(repo_file_path),
200
+ cwd=repo_abspath
201
+ ).split('\0')
238
202
 
239
- from fnmatch import fnmatch
240
-
241
- file_name = path.basename(repo_file_path)
242
- components = self.get_path_components(repo_abspath, path.join(repo_abspath, path.dirname(repo_file_path)))
243
-
244
- is_excluded = False
245
- # We should check all patterns specified in intermediate directories to the given file.
246
- # At the end we should also check for the global patterns (key '()' or empty tuple).
247
- while not is_excluded:
248
- key = tuple(components)
249
- if key in exclude_patterns:
250
- patterns = exclude_patterns[key]
251
- for p in patterns:
252
- if fnmatch(file_name, p) or fnmatch(repo_file_path, p):
253
- self.LOG.debug("Exclude pattern matched {0}: {1}".format(p, repo_file_path))
254
- is_excluded = True
255
-
256
- if not len(components):
257
- break
258
-
259
- components.pop()
260
-
261
- return is_excluded
203
+ try:
204
+ return out[2] == 'set'
205
+ except IndexError:
206
+ return False
262
207
 
263
208
  def archive_all_files(self, archiver):
264
209
  """
@@ -291,14 +236,11 @@ class GitArchiver(object):
291
236
  """
292
237
  repo_abspath = path.join(self.main_repo_abspath, repo_path)
293
238
  repo_file_paths = self.run_git_shell(
294
- "git ls-files --cached --full-name --no-empty-directory",
239
+ 'git ls-files -z --cached --full-name --no-empty-directory',
295
240
  repo_abspath
296
- ).splitlines()
297
- exclude_patterns = self.get_exclude_patterns(repo_abspath, repo_file_paths)
241
+ ).split('\0')[:-1]
298
242
 
299
243
  for repo_file_path in repo_file_paths:
300
- # Git puts path in quotes if file path has unicode characters.
301
- repo_file_path = repo_file_path.strip('"') # file path relative to current repo
302
244
  repo_file_abspath = path.join(repo_abspath, repo_file_path) # absolute file path
303
245
  main_repo_file_path = path.join(repo_path, repo_file_path) # file path relative to the main repo
304
246
 
@@ -306,14 +248,14 @@ class GitArchiver(object):
306
248
  if not path.islink(repo_file_abspath) and path.isdir(repo_file_abspath):
307
249
  continue
308
250
 
309
- if self.is_file_excluded(repo_abspath, repo_file_path, exclude_patterns):
251
+ if self.is_file_excluded(repo_abspath, repo_file_path):
310
252
  continue
311
253
 
312
254
  yield main_repo_file_path
313
255
 
314
256
  if self.force_sub:
315
- self.run_git_shell("git submodule init", repo_abspath)
316
- self.run_git_shell("git submodule update", repo_abspath)
257
+ self.run_git_shell('git submodule init', repo_abspath)
258
+ self.run_git_shell('git submodule update', repo_abspath)
317
259
 
318
260
  try:
319
261
  repo_gitmodules_abspath = path.join(repo_abspath, ".gitmodules")
@@ -322,70 +264,24 @@ class GitArchiver(object):
322
264
  lines = f.readlines()
323
265
 
324
266
  for l in lines:
325
- m = re.match("^\s*path\s*=\s*(.*)\s*$", l)
267
+ m = re.match("^\\s*path\\s*=\\s*(.*)\\s*$", l)
326
268
 
327
269
  if m:
328
- submodule_path = m.group(1)
329
- submodule_path = path.join(repo_path, submodule_path)
270
+ repo_submodule_path = m.group(1) # relative to repo_path
271
+ main_repo_submodule_path = path.join(repo_path, repo_submodule_path) # relative to main_repo_abspath
330
272
 
331
- if self.is_file_excluded(repo_abspath, submodule_path, exclude_patterns):
273
+ if self.is_file_excluded(repo_abspath, repo_submodule_path):
332
274
  continue
333
275
 
334
- for submodule_file_path in self.walk_git_files(submodule_path):
335
- if self.is_file_excluded(repo_abspath, submodule_file_path, exclude_patterns):
276
+ for main_repo_submodule_file_path in self.walk_git_files(main_repo_submodule_path):
277
+ repo_submodule_file_path = main_repo_submodule_file_path.replace(repo_path, "", 1).strip("/")
278
+ if self.is_file_excluded(repo_abspath, repo_submodule_file_path):
336
279
  continue
337
280
 
338
- yield submodule_file_path
281
+ yield main_repo_submodule_file_path
339
282
  except IOError:
340
283
  pass
341
284
 
342
- @staticmethod
343
- def get_path_components(repo_abspath, abspath):
344
- """
345
- Split given abspath into components relative to repo_abspath.
346
- These components are primarily used as unique keys of files and folders within a repository.
347
-
348
- E.g. if repo_abspath is '/Documents/Hobby/ParaView/' and abspath is
349
- '/Documents/Hobby/ParaView/Catalyst/Editions/Base/', function will return:
350
- ['.', 'Catalyst', 'Editions', 'Base']
351
-
352
- First element is always os.curdir (concrete symbol depends on OS).
353
-
354
- @param repo_abspath: Absolute path to the git repository. Normalized via os.path.normpath.
355
- @type repo_abspath: str
356
-
357
- @param abspath: Absolute path to a file within repo_abspath. Normalized via os.path.normpath.
358
- @type abspath: str
359
-
360
- @return: List of path components.
361
- @rtype: list
362
- """
363
- repo_abspath = path.normpath(repo_abspath)
364
- abspath = path.normpath(abspath)
365
-
366
- if not path.isabs(repo_abspath):
367
- raise ValueError("repo_abspath MUST be absolute path.")
368
-
369
- if not path.isabs(abspath):
370
- raise ValueError("abspath MUST be absoulte path.")
371
-
372
- if not path.commonprefix([repo_abspath, abspath]):
373
- raise ValueError(
374
- "abspath (\"{0}\") MUST have common prefix with repo_abspath (\"{1}\")"
375
- .format(abspath, repo_abspath)
376
- )
377
-
378
- components = []
379
-
380
- while not abspath == repo_abspath:
381
- abspath, tail = path.split(abspath)
382
-
383
- if tail:
384
- components.insert(0, tail)
385
-
386
- components.insert(0, curdir)
387
- return components
388
-
389
285
  @staticmethod
390
286
  def run_git_shell(cmd, cwd=None):
391
287
  """
@@ -473,11 +369,9 @@ def main():
473
369
  if options.prefix is not None:
474
370
  options.prefix = path.join(options.prefix, '')
475
371
  else:
476
- import re
477
-
478
372
  output_name = path.basename(output_file_path)
479
373
  output_name = re.sub(
480
- '(\.zip|\.tar|\.tgz|\.txz|\.gz|\.bz2|\.xz|\.tar\.gz|\.tar\.bz2|\.tar\.xz)$',
374
+ '(\\.zip|\\.tar|\\.tbz2|\\.tgz|\\.txz|\\.bz2|\\.gz|\\.xz|\\.tar\\.bz2|\\.tar\\.gz|\\.tar\\.xz)$',
481
375
  '',
482
376
  output_name
483
377
  ) or "Archive"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-git-copy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Schwab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-24 00:00:00.000000000 Z
11
+ date: 2018-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -34,16 +34,16 @@ dependencies:
34
34
  name: bundler
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '1.3'
39
+ version: '0'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "~>"
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
- version: '1.3'
46
+ version: '0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
@@ -59,7 +59,7 @@ dependencies:
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
- name: yard
62
+ name: rubocop
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - ">="
@@ -80,7 +80,9 @@ extensions: []
80
80
  extra_rdoc_files: []
81
81
  files:
82
82
  - ".gitignore"
83
+ - ".gitlab-ci.yml"
83
84
  - ".gitmodules"
85
+ - ".rubocop.yml"
84
86
  - CHANGELOG.md
85
87
  - Gemfile
86
88
  - LICENSE.txt
@@ -89,10 +91,11 @@ files:
89
91
  - capistrano-git-copy.gemspec
90
92
  - lib/capistrano/git_copy.rb
91
93
  - lib/capistrano/git_copy/scm.rb
94
+ - lib/capistrano/git_copy/scm_helpers.rb
92
95
  - lib/capistrano/git_copy/tasks/git_copy.rake
93
96
  - lib/capistrano/git_copy/version.rb
94
97
  - vendor/git-archive-all/git_archive_all.py
95
- homepage: https://github.com/ydkn/capistrano-git-copy
98
+ homepage: https://gitlab.com/ydkn/capistrano-git-copy
96
99
  licenses:
97
100
  - MIT
98
101
  metadata: {}
@@ -112,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
115
  version: '0'
113
116
  requirements: []
114
117
  rubyforge_project:
115
- rubygems_version: 2.7.6
118
+ rubygems_version: 2.7.7
116
119
  signing_key:
117
120
  specification_version: 4
118
121
  summary: Copy local git repository deploy strategy for capistrano.