capistrano-git-copy 1.5.5 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 911c6595d192844b5881b0d8a8cebc22807c1e05cb1f239180f88f75382c23df
4
- data.tar.gz: 36ba77b942dbc78b60dc6aa3e21e2366d4ec42ac1c301c363adf5ee99efce925
3
+ metadata.gz: 447065540bb8fa941ac498cc168caeacac3f44c04f35b9dcac56b99b971359da
4
+ data.tar.gz: f112754d2f94ebfa49ae6f8360318f362e006fb66a687e27e5d68eb1bbd87a9a
5
5
  SHA512:
6
- metadata.gz: 6fdd39263057a50cf376c39dae078baf56314fc37e864d66b093e3ce8fad42974d1422c3697588c77b6c0c02255b9b0a251ee032d6c72e627ca4a1ffcd847c9c
7
- data.tar.gz: efacaa507ac8796d60c21c329dde4920f52c9ce456a6031320973db3f5c2d32a4defb32fe489abf64c388c3d1a718f60e8275bd57534d934521eb8f4158748d0
6
+ metadata.gz: 71daf64e5bcc8d77bdec87c24ffa90b1b0c7e9d370a49719ba8afea79b966ff1318a1a7d1ea2b8ff98f21eb2f14e4f45da71514d21c9a2cd30b43a52d4e68229
7
+ data.tar.gz: eb902360bbbcbef39d11d0c2058ff42f5936129a4963818d731606bfde0176d5d01781f4a26c7b879f650fbc0cc2925cce5b1f5296cacc63550d11f738a80a0e
@@ -27,7 +27,6 @@ dependency_scanning:
27
27
  image: docker:stable
28
28
  variables:
29
29
  DOCKER_DRIVER: overlay2
30
- allow_failure: true
31
30
  services:
32
31
  - docker:stable-dind
33
32
  script:
@@ -2,7 +2,7 @@ require:
2
2
  - rubocop-performance
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.3
5
+ TargetRubyVersion: 2.4
6
6
 
7
7
  Metrics/LineLength:
8
8
  Max: 120
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.5.6] - 2019-11-10
10
+ ### Changed
11
+ - updated _git-archive-all_ to 1.20.0
12
+
9
13
  ## [1.5.5] - 2019-06-19
10
14
  ### Fixed
11
15
  - usage with git versions >= 2.22.0
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'bundler'
25
25
  spec.add_development_dependency 'rake'
26
26
  spec.add_development_dependency 'rubocop'
27
+ spec.add_development_dependency 'rubocop-performance'
27
28
  end
@@ -5,6 +5,6 @@ module Capistrano
5
5
  # GitCopy
6
6
  module GitCopy
7
7
  # gem version
8
- VERSION = '1.5.5'
8
+ VERSION = '1.5.6'
9
9
  end
10
10
  end
@@ -32,24 +32,88 @@ from subprocess import CalledProcessError, Popen, PIPE
32
32
  import sys
33
33
  import re
34
34
 
35
- __version__ = "1.19.4"
35
+ __version__ = "1.20.0"
36
36
 
37
37
 
38
38
  try:
39
- # Python 3.3+
40
- from shlex import quote
39
+ # Python 3.2+
40
+ from os import fsdecode
41
41
  except ImportError:
42
- _find_unsafe = re.compile(r'[^a-zA-Z0-9_@%+=:,./-]').search
42
+ def fsdecode(filename):
43
+ if not isinstance(filename, unicode):
44
+ return filename.decode(sys.getfilesystemencoding(), 'strict')
45
+ else:
46
+ return filename
47
+
48
+ try:
49
+ # Python 3.2+
50
+ from os import fsencode
51
+ except ImportError:
52
+ def fsencode(filename):
53
+ if not isinstance(filename, bytes):
54
+ return filename.encode(sys.getfilesystemencoding(), 'strict')
55
+ else:
56
+ return filename
57
+
58
+
59
+ def git_fsdecode(filename):
60
+ """
61
+ Decode filename from git output into str.
62
+ """
63
+ if sys.platform.startswith('win32'):
64
+ return filename.decode('utf-8')
65
+ else:
66
+ return fsdecode(filename)
67
+
68
+
69
+ def git_fsencode(filename):
70
+ """
71
+ Encode filename from str into git input.
72
+ """
73
+ if sys.platform.startswith('win32'):
74
+ return filename.encode('utf-8')
75
+ else:
76
+ return fsencode(filename)
77
+
78
+
79
+ try:
80
+ # Python 3.6+
81
+ from os import fspath as _fspath
43
82
 
44
- def quote(s):
45
- """Return a shell-escaped version of the string *s*."""
46
- if not s:
47
- return "''"
83
+ def fspath(filename, decoder=fsdecode, encoder=fsencode):
84
+ """
85
+ Convert filename into bytes or str, depending on what's the best type
86
+ to represent paths for current Python and platform.
87
+ """
88
+ # Python 3.6+: str can represent any path (PEP 383)
89
+ # str is not required on Windows (PEP 529)
90
+ # Decoding is still applied for consistency and to follow PEP 519 recommendation.
91
+ return decoder(_fspath(filename))
92
+ except ImportError:
93
+ def fspath(filename, decoder=fsdecode, encoder=fsencode):
94
+ # Python 3.4 and 3.5: str can represent any path (PEP 383),
95
+ # but str is required on Windows (no PEP 529)
96
+ #
97
+ # Python 2.6 and 2.7: str cannot represent any path (no PEP 383),
98
+ # str is required on Windows (no PEP 529)
99
+ # bytes is required on POSIX (no PEP 383)
100
+ if sys.version_info > (3,):
101
+ import pathlib
102
+ if isinstance(filename, pathlib.PurePath):
103
+ return str(filename)
104
+ else:
105
+ return decoder(filename)
106
+ elif sys.platform.startswith('win32'):
107
+ return decoder(filename)
108
+ else:
109
+ return encoder(filename)
48
110
 
49
- if _find_unsafe(s) is None:
50
- return s
51
111
 
52
- return "'" + s.replace("'", "'\"'\"'") + "'"
112
+ def git_fspath(filename):
113
+ """
114
+ fspath representation of git output.
115
+ """
116
+ return fspath(filename, git_fsdecode, git_fsencode)
53
117
 
54
118
 
55
119
  class GitArchiver(object):
@@ -85,54 +149,43 @@ class GitArchiver(object):
85
149
  baz
86
150
  foo/
87
151
  bar
88
- @type prefix: str
89
152
 
90
153
  @param exclude: Determines whether archiver should follow rules specified in .gitattributes files.
91
- @type exclude: bool
92
154
 
93
155
  @param force_sub: Determines whether submodules are initialized and updated before archiving.
94
- @type force_sub: bool
95
156
 
96
157
  @param extra: List of extra paths to include in the resulting archive.
97
- @type extra: list
98
158
 
99
159
  @param main_repo_abspath: Absolute path to the main repository (or one of subdirectories).
100
160
  If given path is path to a subdirectory (but not a submodule directory!) it will be replaced
101
161
  with abspath to top-level directory of the repository.
102
162
  If None, current cwd is used.
103
- @type main_repo_abspath: str
104
163
 
105
164
  @param git_version: Version of Git that determines whether various workarounds are on.
106
165
  If None, tries to resolve via Git's CLI.
107
- @type git_version: tuple or None
108
166
  """
167
+ self._should_decode_path = None
168
+ self._check_attr_gens = {}
169
+
109
170
  if git_version is None:
110
171
  git_version = self.get_git_version()
111
172
 
112
173
  if git_version is not None and git_version < (1, 6, 1):
113
174
  raise ValueError("git of version 1.6.1 and higher is required")
114
175
 
115
- if extra is None:
116
- extra = []
176
+ self.git_version = git_version
117
177
 
118
178
  if main_repo_abspath is None:
119
179
  main_repo_abspath = path.abspath('')
120
180
  elif not path.isabs(main_repo_abspath):
121
181
  raise ValueError("main_repo_abspath must be an absolute path")
122
182
 
123
- try:
124
- main_repo_abspath = path.abspath(self.run_git_shell('git rev-parse --show-toplevel', main_repo_abspath).rstrip())
125
- except CalledProcessError:
126
- raise ValueError("{0} is not part of a git repository".format(main_repo_abspath))
183
+ self.main_repo_abspath = self.resolve_git_main_repo_abspath(main_repo_abspath)
127
184
 
128
- self.prefix = prefix
185
+ self.prefix = fspath(prefix)
129
186
  self.exclude = exclude
130
- self.extra = extra
187
+ self.extra = [fspath(e) for e in extra] if extra is not None else []
131
188
  self.force_sub = force_sub
132
- self.main_repo_abspath = main_repo_abspath
133
- self.git_version = git_version
134
-
135
- self._check_attr_gens = {}
136
189
 
137
190
  def create(self, output_path, dry_run=False, output_format=None, compresslevel=None):
138
191
  """
@@ -142,15 +195,16 @@ class GitArchiver(object):
142
195
  Supported formats are: gz, zip, bz2, xz, tar, tgz, txz
143
196
 
144
197
  @param output_path: Output file path.
145
- @type output_path: str
146
198
 
147
199
  @param dry_run: Determines whether create should do nothing but print what it would archive.
148
- @type dry_run: bool
149
200
 
150
201
  @param output_format: Determines format of the output archive. If None, format is determined from extension
151
202
  of output_file_path.
152
- @type output_format: str
203
+
204
+ @param compresslevel: Optional compression level. Interpretation depends on the output format.
153
205
  """
206
+ output_path = fspath(output_path)
207
+
154
208
  if output_format is None:
155
209
  file_name, file_ext = path.splitext(output_path)
156
210
  output_format = file_ext[len(extsep):].lower()
@@ -195,13 +249,13 @@ class GitArchiver(object):
195
249
  raise ValueError("unknown format: {0}".format(output_format))
196
250
 
197
251
  def archiver(file_path, arcname):
198
- self.LOG.debug("{0} => {1}".format(file_path, arcname))
252
+ self.LOG.debug(fspath("{0} => {1}").format(file_path, arcname))
199
253
  add_file(file_path, arcname)
200
254
  else:
201
255
  archive = None
202
256
 
203
257
  def archiver(file_path, arcname):
204
- self.LOG.info("{0} => {1}".format(file_path, arcname))
258
+ self.LOG.info(fspath("{0} => {1}").format(file_path, arcname))
205
259
 
206
260
  self.archive_all_files(archiver)
207
261
 
@@ -213,17 +267,14 @@ class GitArchiver(object):
213
267
  Checks whether file at a given path is excluded.
214
268
 
215
269
  @param repo_abspath: Absolute path to the git repository.
216
- @type repo_abspath: str
217
270
 
218
271
  @param repo_file_path: Path to a file relative to repo_abspath.
219
- @type repo_file_path: str
220
272
 
221
273
  @return: True if file should be excluded. Otherwise False.
222
- @rtype: bool
223
274
  """
224
275
  next(self._check_attr_gens[repo_abspath])
225
276
  attrs = self._check_attr_gens[repo_abspath].send(repo_file_path)
226
- return attrs['export-ignore'] == 'set'
277
+ return attrs['export-ignore'] == b'set'
227
278
 
228
279
  def archive_all_files(self, archiver):
229
280
  """
@@ -231,7 +282,6 @@ class GitArchiver(object):
231
282
 
232
283
  @param archiver: Callable that accepts 2 arguments:
233
284
  abspath to file on the system and relative path within archive.
234
- @type archiver: Callable
235
285
  """
236
286
  for file_path in self.extra:
237
287
  archiver(path.abspath(file_path), path.join(self.prefix, file_path))
@@ -239,7 +289,7 @@ class GitArchiver(object):
239
289
  for file_path in self.walk_git_files():
240
290
  archiver(path.join(self.main_repo_abspath, file_path), path.join(self.prefix, file_path))
241
291
 
242
- def walk_git_files(self, repo_path=''):
292
+ def walk_git_files(self, repo_path=fspath('')):
243
293
  """
244
294
  An iterator method that yields a file path relative to main_repo_abspath
245
295
  for each file that should be included in the archive.
@@ -249,20 +299,24 @@ class GitArchiver(object):
249
299
  Recurs into submodules as well.
250
300
 
251
301
  @param repo_path: Path to the git submodule repository relative to main_repo_abspath.
252
- @type repo_path: str
253
302
 
254
303
  @return: Iterator to traverse files under git control relative to main_repo_abspath.
255
- @rtype: Iterable
256
304
  """
257
- repo_abspath = path.join(self.main_repo_abspath, repo_path)
305
+ repo_abspath = path.join(self.main_repo_abspath, fspath(repo_path))
258
306
  assert repo_abspath not in self._check_attr_gens
259
- self._check_attr_gens[repo_abspath] = self.check_attr(repo_abspath, ['export-ignore'])
307
+ self._check_attr_gens[repo_abspath] = self.check_git_attr(repo_abspath, ['export-ignore'])
260
308
 
261
309
  try:
262
310
  repo_file_paths = self.run_git_shell(
263
311
  'git ls-files -z --cached --full-name --no-empty-directory',
264
- repo_abspath
265
- ).split('\0')[:-1]
312
+ cwd=repo_abspath
313
+ )
314
+ repo_file_paths = repo_file_paths.split(b'\0')[:-1]
315
+
316
+ if sys.platform.startswith('win32'):
317
+ repo_file_paths = (git_fspath(p.replace(b'/', b'\\')) for p in repo_file_paths)
318
+ else:
319
+ repo_file_paths = map(git_fspath, repo_file_paths)
266
320
 
267
321
  for repo_file_path in repo_file_paths:
268
322
  repo_file_abspath = path.join(repo_abspath, repo_file_path) # absolute file path
@@ -282,7 +336,7 @@ class GitArchiver(object):
282
336
  self.run_git_shell('git submodule update', repo_abspath)
283
337
 
284
338
  try:
285
- repo_gitmodules_abspath = path.join(repo_abspath, ".gitmodules")
339
+ repo_gitmodules_abspath = path.join(repo_abspath, fspath(".gitmodules"))
286
340
 
287
341
  with open(repo_gitmodules_abspath) as f:
288
342
  lines = f.readlines()
@@ -291,7 +345,7 @@ class GitArchiver(object):
291
345
  m = re.match("^\\s*path\\s*=\\s*(.*)\\s*$", l)
292
346
 
293
347
  if m:
294
- repo_submodule_path = m.group(1) # relative to repo_path
348
+ repo_submodule_path = fspath(m.group(1)) # relative to repo_path
295
349
  main_repo_submodule_path = path.join(repo_path, repo_submodule_path) # relative to main_repo_abspath
296
350
 
297
351
  if self.is_file_excluded(repo_abspath, repo_submodule_path):
@@ -309,22 +363,19 @@ class GitArchiver(object):
309
363
  self._check_attr_gens[repo_abspath].close()
310
364
  del self._check_attr_gens[repo_abspath]
311
365
 
312
- def check_attr(self, repo_abspath, attrs):
366
+ def check_git_attr(self, repo_abspath, attrs):
313
367
  """
314
- Generator that returns attributes for given paths relative to repo_abspath.
368
+ Generator that returns git attributes for received paths relative to repo_abspath.
315
369
 
316
- >>> g = GitArchiver.check_attr('repo_path', ['export-ignore'])
370
+ >>> archiver = GitArchiver(...)
371
+ >>> g = archiver.check_git_attr('repo_path', ['export-ignore'])
317
372
  >>> next(g)
318
373
  >>> attrs = g.send('relative_path')
319
374
  >>> print(attrs['export-ignore'])
320
375
 
321
376
  @param repo_abspath: Absolute path to a git repository.
322
- @type repo_abspath: str
323
377
 
324
- @param attrs: Attributes to check.
325
- @type attrs: [str]
326
-
327
- @rtype: generator
378
+ @param attrs: Attributes to check
328
379
  """
329
380
  def make_process():
330
381
  env = dict(environ, GIT_FLUSH='1')
@@ -332,7 +383,7 @@ class GitArchiver(object):
332
383
  return Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, cwd=repo_abspath, env=env)
333
384
 
334
385
  def read_attrs(process, repo_file_path):
335
- process.stdin.write(repo_file_path.encode('utf-8') + b'\0')
386
+ process.stdin.write(repo_file_path + b'\0')
336
387
  process.stdin.flush()
337
388
 
338
389
  # For every attribute check-attr will output: <path> NUL <attribute> NUL <info> NUL
@@ -349,7 +400,8 @@ class GitArchiver(object):
349
400
  nuls_count += 1
350
401
 
351
402
  if nuls_count % 3 == 0:
352
- yield map(self.decode_git_output, (path, attr, info))
403
+ yield path, attr, info
404
+
353
405
  path, attr, info = b'', b'', b''
354
406
  elif nuls_count % 3 == 0:
355
407
  path += b
@@ -362,7 +414,7 @@ class GitArchiver(object):
362
414
  """
363
415
  Compatibility with versions 1.8.5 and below that do not recognize -z for output.
364
416
  """
365
- process.stdin.write(repo_file_path.encode('utf-8') + b'\0')
417
+ process.stdin.write(repo_file_path + b'\0')
366
418
  process.stdin.flush()
367
419
 
368
420
  # For every attribute check-attr will output: <path>: <attribute>: <info>\n
@@ -383,11 +435,11 @@ class GitArchiver(object):
383
435
  if attr_start == -1:
384
436
  raise RuntimeError("unexpected output of check-attr: {0}".format(line))
385
437
 
386
- info = line[info_start + 2:len(line) - 1] # trim leading ": " and trailing \n
387
- attr = line[attr_start + 2:info_start] # trim leading ": "
388
438
  path = line[:attr_start]
439
+ attr = line[attr_start + 2:info_start] # trim leading ": "
440
+ info = line[info_start + 2:len(line) - 1] # trim leading ": " and trailing \n
441
+ yield path, attr, info
389
442
 
390
- yield map(self.decode_git_output, (path, attr, info))
391
443
  lines_count += 1
392
444
 
393
445
  if not attrs:
@@ -395,17 +447,19 @@ class GitArchiver(object):
395
447
 
396
448
  process = make_process()
397
449
 
450
+ if self.git_version is None or self.git_version > (1, 8, 5):
451
+ reader = read_attrs
452
+ else:
453
+ reader = read_attrs_old
454
+
398
455
  try:
399
456
  while True:
400
457
  repo_file_path = yield
458
+ repo_file_path = git_fsencode(fspath(repo_file_path))
401
459
  repo_file_attrs = {}
402
460
 
403
- if self.git_version is None or self.git_version > (1, 8, 5):
404
- reader = read_attrs
405
- else:
406
- reader = read_attrs_old
407
-
408
461
  for path, attr, value in reader(process, repo_file_path):
462
+ attr = attr.decode('utf-8')
409
463
  repo_file_attrs[attr] = value
410
464
 
411
465
  yield repo_file_attrs
@@ -413,36 +467,31 @@ class GitArchiver(object):
413
467
  process.stdin.close()
414
468
  process.wait()
415
469
 
416
- @classmethod
417
- def decode_git_output(cls, output):
470
+ def resolve_git_main_repo_abspath(self, abspath):
418
471
  """
419
- Decode Git's binary output handeling the way it escapes unicode characters.
420
-
421
- @type output: bytes
422
-
423
- @rtype: str
472
+ Return absolute path to the repo for a given path.
424
473
  """
425
- return output.decode('unicode_escape').encode('raw_unicode_escape').decode('utf-8')
474
+ try:
475
+ main_repo_abspath = self.run_git_shell('git rev-parse --show-toplevel', cwd=abspath).rstrip()
476
+ return path.abspath(git_fspath(main_repo_abspath))
477
+ except CalledProcessError as e:
478
+ raise ValueError("{0} is not part of a git repository ({1})".format(abspath, e.returncode))
426
479
 
427
480
  @classmethod
428
481
  def run_git_shell(cls, cmd, cwd=None):
429
482
  """
430
- Runs git shell command, reads output and decodes it into unicode string.
483
+ Run git shell command, read output and decode it into a unicode string.
431
484
 
432
485
  @param cmd: Command to be executed.
433
- @type cmd: str
434
486
 
435
- @type cwd: str
436
487
  @param cwd: Working directory.
437
488
 
438
- @rtype: str
439
489
  @return: Output of the command.
440
490
 
441
491
  @raise CalledProcessError: Raises exception if return code of the command is non-zero.
442
492
  """
443
493
  p = Popen(cmd, shell=True, stdout=PIPE, cwd=cwd)
444
494
  output, _ = p.communicate()
445
- output = cls.decode_git_output(output)
446
495
 
447
496
  if p.returncode:
448
497
  if sys.version_info > (2, 6):
@@ -458,8 +507,6 @@ class GitArchiver(object):
458
507
  Return version of git current shell points to.
459
508
 
460
509
  If version cannot be parsed None is returned.
461
-
462
- @rtype: tuple or None
463
510
  """
464
511
  try:
465
512
  output = cls.run_git_shell('git version')
@@ -474,18 +521,21 @@ class GitArchiver(object):
474
521
  return None
475
522
 
476
523
  try:
477
- return tuple(int(v) for v in version.split('.'))
524
+ return tuple(int(v) if v.isdigit() else 0 for v in version.split(b'.'))
478
525
  except ValueError:
479
526
  cls.LOG.warning("Unable to parse Git version \"%s\".", version)
480
527
  return None
481
528
 
482
529
 
483
- def main():
530
+ def main(argv=None):
531
+ if argv is None:
532
+ argv = sys.argv
533
+
484
534
  from optparse import OptionParser, SUPPRESS_HELP
485
535
 
486
536
  parser = OptionParser(
487
- usage="usage: %prog [-v] [--prefix PREFIX] [--no-exclude] [--force-submodules]"
488
- " [--extra EXTRA1 ...] [--dry-run] [-0 | ... | -9] OUTPUT_FILE",
537
+ usage="usage: %prog [-v] [-C BASE_REPO] [--prefix PREFIX] [--no-exclude]"
538
+ " [--force-submodules] [--extra EXTRA1 ...] [--dry-run] [-0 | ... | -9] OUTPUT_FILE",
489
539
  version="%prog {0}".format(__version__)
490
540
  )
491
541
 
@@ -497,6 +547,13 @@ def main():
497
547
  OUTPUT_FILE name is used by default to avoid tarbomb.
498
548
  You can set it to '' in order to explicitly request tarbomb""")
499
549
 
550
+ parser.add_option('-C',
551
+ type='string',
552
+ dest='base_repo',
553
+ default=None,
554
+ help="""use BASE_REPO as the main repository git working directory to archive.
555
+ Defaults to current directory when empty""")
556
+
500
557
  parser.add_option('-v', '--verbose',
501
558
  action='store_true',
502
559
  dest='verbose',
@@ -531,7 +588,7 @@ def main():
531
588
  dest='compresslevel',
532
589
  help=SUPPRESS_HELP)
533
590
 
534
- options, args = parser.parse_args()
591
+ options, args = parser.parse_args(argv[1:])
535
592
 
536
593
  if len(args) != 1:
537
594
  parser.error("You must specify exactly one output file")
@@ -561,13 +618,15 @@ def main():
561
618
  archiver = GitArchiver(options.prefix,
562
619
  options.exclude,
563
620
  options.force_sub,
564
- options.extra)
621
+ options.extra,
622
+ path.abspath(options.base_repo) if options.base_repo is not None else None
623
+ )
565
624
  archiver.create(output_file_path, options.dry_run, compresslevel=options.compresslevel)
566
625
  except Exception as e:
567
626
  parser.exit(2, "{0}\n".format(e))
568
627
 
569
- sys.exit(0)
628
+ return 0
570
629
 
571
630
 
572
631
  if __name__ == '__main__':
573
- main()
632
+ sys.exit(main())
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.5
4
+ version: 1.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Schwab
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-19 00:00:00.000000000 Z
11
+ date: 2019-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -72,6 +72,20 @@ dependencies:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubocop-performance
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
75
89
  description: Copy local git repository deploy strategy for capistrano.
76
90
  email:
77
91
  - me@ydkn.de
@@ -114,7 +128,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
128
  - !ruby/object:Gem::Version
115
129
  version: '0'
116
130
  requirements: []
117
- rubygems_version: 3.0.3
131
+ rubygems_version: 3.0.6
118
132
  signing_key:
119
133
  specification_version: 4
120
134
  summary: Copy local git repository deploy strategy for capistrano.