eac_git 0.3.0 → 0.4.1

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: 28dd90f9f4093cb73e60e731a5f759177d9e960784b540be3d8c0516c432a6fa
4
- data.tar.gz: 81b8d1a37d8faa5729ed508edea4038444b988aed0e54996a998fd3ae4ff7bf7
3
+ metadata.gz: 88f33243bc2e7b99f0401b45a82c09f2b83179b716258566c2a02bf22b8e783a
4
+ data.tar.gz: d8364ba8382bc2a8cdbcf452a863d59ef0f40b4c94e093c5c487b6a9b26d8117
5
5
  SHA512:
6
- metadata.gz: 0f8d0081d1cb643126c51692008197cdad248e127441dac1dd8c273a12d2f81ed0245daa1928d06126ea2b685bd837aa5b98eab757bdd4a8430de78fafeb5286
7
- data.tar.gz: 91b807fe713fae5dfe3aab764a140e079f4c4ec0a364f18ebd50a3066fbab3445f31c7b11c722913e08a7f91e21003d0d34abaf5254ebf9c0b23e923b12e10bf
6
+ metadata.gz: a666558266a77e58f614a8bd512d2cc8b4b8f0593c6f5feb0f8d926e3fae99098b96ea6c38fc5890fb41ebfac317fda13815ff33f3c69482a3856fcf67008cfd
7
+ data.tar.gz: e15684fb5458ba30546e13d89bc7186b3d542a8a32606a0749f543715a8c570781425ae80bb9deb1b6723abf101b1c2d8e10fd498880a6bfbc0f17ea26e03b74
data/lib/eac_git/local.rb CHANGED
@@ -12,6 +12,10 @@ module EacGit
12
12
  self.root_path = root_path.to_pathname
13
13
  end
14
14
 
15
+ def commit(ref, required = false)
16
+ rev_parse(ref, required).if_present { |v| ::EacGit::Local::Commit.new(self, v) }
17
+ end
18
+
15
19
  def descendant?(descendant, ancestor)
16
20
  base = merge_base(descendant, ancestor)
17
21
  return false if base.blank?
@@ -48,6 +52,10 @@ module EacGit
48
52
  ::EacGit::Local::Subrepo.new(self, subpath)
49
53
  end
50
54
 
55
+ def to_s
56
+ "#{self.class}[#{root_path}]"
57
+ end
58
+
51
59
  private
52
60
 
53
61
  def merge_base_pair(commit1, commit2)
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacGit
6
+ class Local
7
+ class Commit
8
+ require_sub __FILE__, include_modules: true
9
+ enable_simple_cache
10
+
11
+ FIELDS = {
12
+ author_name: '%an', author_email: '%ae', author_date: '%ai',
13
+ subject: '%s',
14
+ author_all: '%an <%ae>, %ai',
15
+ commiter_name: '%cn', commiter_email: '%ce', commiter_date: '%ci',
16
+ commiter_all: '%cn <%ce>, %ci'
17
+ }.freeze
18
+
19
+ common_constructor :repo, :hash
20
+
21
+ def format(format)
22
+ repo.command('--no-pager', 'log', '-1', "--pretty=format:#{format}", hash).execute!.strip
23
+ end
24
+
25
+ FIELDS.each do |field, format|
26
+ define_method(field) { format(format) }
27
+ end
28
+
29
+ def changed_files_uncached
30
+ diff_tree_execute.each_line.map do |line|
31
+ ::EacGit::Local::Commit::ChangedFile.new(self, line)
32
+ end
33
+ end
34
+
35
+ def changed_files_size_uncached
36
+ changed_files.inject(0) { |a, e| a + e.dst_size }
37
+ end
38
+
39
+ def root_child?
40
+ format('%P').blank?
41
+ end
42
+
43
+ private
44
+
45
+ def diff_tree_execute
46
+ args = []
47
+ args << '--root' if root_child?
48
+ args << hash
49
+ repo.command(*::EacGit::Local::Commit::DiffTreeLine::GIT_COMMAND_ARGS, *args).execute!
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_git/local/commit/diff_tree_line'
5
+
6
+ module EacGit
7
+ class Local
8
+ class Commit
9
+ class ChangedFile
10
+ enable_simple_cache
11
+
12
+ attr_reader :commit, :diff_tree
13
+
14
+ # @param commit [EacGit::Local::Commit]
15
+ # @param diff_tree_line [String] A line from command "repo diff-tree --no-commit-id -r
16
+ # --full-index"'s output.
17
+ def initialize(commit, diff_tree_line)
18
+ @commit = commit
19
+ @diff_tree = ::EacGit::Local::Commit::DiffTreeLine.new(diff_tree_line)
20
+ end
21
+
22
+ delegate(*::EacGit::Local::Commit::DiffTreeLine::FIELDS, to: :diff_tree)
23
+
24
+ def to_s
25
+ "#{path}|#{status}"
26
+ end
27
+
28
+ def src_size_uncached
29
+ size(src_sha1)
30
+ end
31
+
32
+ def dst_size_uncached
33
+ size(dst_sha1)
34
+ end
35
+
36
+ private
37
+
38
+ def size(id)
39
+ return 0 if /\A0+\z/.match(id)
40
+
41
+ commit.repo.command('cat-file', '-s', id).execute!.strip.to_i
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacGit
4
+ class Local
5
+ class Commit
6
+ class DiffTreeLine
7
+ DIFF_TREE_PATTERN = /\A:(\d{6}) (\d{6}) (\S+) (\S+) (\S+)\t(\S.*)\z/.freeze
8
+ FIELDS = %w[src_mode dst_mode src_sha1 dst_sha1 status path].freeze
9
+ GIT_COMMAND_ARGS = %w[-c core.quotepath=off diff-tree --no-commit-id -r --full-index].freeze
10
+
11
+ attr_reader(*FIELDS)
12
+
13
+ # line: a line of command "git [GIT_COMMAND_ARGS]"'s output.
14
+ # Reference: https://git-scm.com/docs/git-diff-tree
15
+ def initialize(line)
16
+ m = DIFF_TREE_PATTERN.match(line.strip)
17
+ raise "\"#{line}\" did not match pattern" unless m
18
+
19
+ FIELDS.count.times { |i| send("#{FIELDS[i]}=", m[i + 1]) }
20
+ end
21
+
22
+ def fields
23
+ FIELDS.map { |field| [field, send(field)] }.to_h
24
+ end
25
+
26
+ private
27
+
28
+ attr_writer(*FIELDS)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -20,9 +20,8 @@ module EacGit
20
20
  end
21
21
 
22
22
  def dirty_files
23
- command('status', '--porcelain', '--untracked-files').execute!.each_line.map do |line|
24
- parse_status_line(line.gsub(/\n\z/, ''))
25
- end
23
+ command('status', '--porcelain=v1', '--untracked-files', '--no-renames')
24
+ .execute!.each_line.map { |line| parse_status_line(line.gsub(/\n\z/, '')) }
26
25
  end
27
26
 
28
27
  private
data/lib/eac_git/rspec.rb CHANGED
@@ -5,12 +5,17 @@ require 'eac_git/executables'
5
5
 
6
6
  module EacGit
7
7
  module Rspec
8
+ require_sub __FILE__
9
+
8
10
  class << self
9
11
  def configure
10
12
  ::EacRubyUtils::Rspec::Conditional.default.add(:git) do
11
13
  ::EacGit::Executables.git.validate
12
14
  end
13
- RSpec.configure { |config| ::EacRubyUtils::Rspec::Conditional.default.configure(config) }
15
+ RSpec.configure do |config|
16
+ ::EacRubyUtils::Rspec::Conditional.default.configure(config)
17
+ config.include ::EacGit::Rspec::StubbedGitLocalRepo
18
+ end
14
19
  end
15
20
  end
16
21
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_git/local'
4
+ require 'eac_ruby_utils/envs'
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+
8
+ module EacGit
9
+ module Rspec
10
+ module StubbedGitLocalRepo
11
+ def stubbed_git_local_repo(bare = false)
12
+ path = ::Dir.mktmpdir
13
+ ::EacRubyUtils::Envs.local.command(stubbed_git_local_repo_args(path, bare)).execute!
14
+ repo = StubbedGitRepository.new(path)
15
+ repo.command('config', 'user.email', 'theuser@example.net').execute!
16
+ repo.command('config', 'user.name', 'The User').execute!
17
+ repo
18
+ end
19
+
20
+ private
21
+
22
+ def stubbed_git_local_repo_args(path, bare)
23
+ r = %w[git init]
24
+ r << '--bare' if bare
25
+ r + [path]
26
+ end
27
+
28
+ class StubbedGitRepository < ::EacGit::Local
29
+ def file(*subpath)
30
+ StubbedGitRepositoryFile.new(self, subpath)
31
+ end
32
+ end
33
+
34
+ class StubbedGitRepositoryFile
35
+ attr_reader :git, :subpath
36
+
37
+ def initialize(git, subpath)
38
+ @git = git
39
+ @subpath = subpath
40
+ end
41
+
42
+ def path
43
+ git.root_path.join(*subpath)
44
+ end
45
+
46
+ def touch
47
+ ::FileUtils.touch(path.to_path)
48
+ end
49
+
50
+ def delete
51
+ path.unlink
52
+ end
53
+
54
+ def write(content)
55
+ path.write(content)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacGit
4
- VERSION = '0.3.0'
4
+ VERSION = '0.4.1'
5
5
  end
@@ -8,6 +8,8 @@
8
8
  # Exit on any errors:
9
9
  set -e
10
10
 
11
+ export FILTER_BRANCH_SQUELCH_WARNING=1
12
+
11
13
  # Import Bash+ helper functions:
12
14
  SOURCE="$BASH_SOURCE"
13
15
  while [[ -h $SOURCE ]]; do
@@ -549,7 +551,7 @@ subrepo:pull() {
549
551
  fi
550
552
  else
551
553
  o "Merge in changes from $refs_subrepo_fetch"
552
- FAIL=false OUT=true RUN git merge "$refs_subrepo_fetch"
554
+ FAIL=false RUN git merge "$refs_subrepo_fetch"
553
555
  if ! OK; then
554
556
  say "The \"git merge\" command failed:"
555
557
  say
@@ -765,8 +767,8 @@ subrepo:branch() {
765
767
  o "Create with content"
766
768
  local PREVIOUS_IFS=$IFS
767
769
  IFS=$'\n'
768
- local author_info=( $(git log -1 --format=%ad%n%ae%n%an "$commit") )
769
- local commiter_info=( $(git log -1 --format=%cd%n%ce%n%cn "$commit") )
770
+ local author_info=( $(git log -1 --date=default --format=%ad%n%ae%n%an "$commit") )
771
+ local commiter_info=( $(git log -1 --date=default --format=%cd%n%ce%n%cn "$commit") )
770
772
  IFS=$PREVIOUS_IFS
771
773
 
772
774
  # When we create new commits we leave the author information unchanged
@@ -774,7 +776,7 @@ subrepo:branch() {
774
776
  # This should be analog how cherrypicking is handled allowing git
775
777
  # to store both the original author but also the responsible committer
776
778
  # that created the local version of the commit and pushed it.
777
- prev_commit=$(git log -n 1 --format=%B "$commit" |
779
+ prev_commit=$(git log -n 1 --date=default --format=%B "$commit" |
778
780
  GIT_AUTHOR_DATE="${author_info[0]}" \
779
781
  GIT_AUTHOR_EMAIL="${author_info[1]}" \
780
782
  GIT_AUTHOR_NAME="${author_info[2]}" \
@@ -959,7 +961,7 @@ subrepo:clean() {
959
961
 
960
962
  o "Clean $subdir"
961
963
  git:remove-worktree
962
- if [[ -e .git/$ref ]]; then
964
+ if git:branch-exists "$branch"; then
963
965
  o "Remove branch '$branch'."
964
966
  RUN git update-ref -d "$ref"
965
967
  clean_list+=("branch '$branch'")
@@ -1505,7 +1507,7 @@ assert-subdir-ready-for-init() {
1505
1507
  error "The subdir '$subdir' is already a subrepo."
1506
1508
  fi
1507
1509
  # Check that subdir is part of the repo
1508
- if [[ -z $(git log -1 -- $subdir) ]]; then
1510
+ if [[ -z $(git log -1 --date=default -- $subdir) ]]; then
1509
1511
  error "The subdir '$subdir' is not part of this repo."
1510
1512
  fi
1511
1513
  }
@@ -1535,7 +1537,7 @@ get-all-subrepos() {
1535
1537
  add-subrepo() {
1536
1538
  if ! $ALL_wanted; then
1537
1539
  for path in "${subrepos[@]}"; do
1538
- [[ $1 =~ ^$path ]] && return
1540
+ [[ $1/ =~ ^$path/ ]] && return
1539
1541
  done
1540
1542
  fi
1541
1543
  subrepos+=("$1")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eac_git
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Put here the authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-26 00:00:00.000000000 Z
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: eac_ruby_utils
@@ -44,6 +44,20 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 1.0.8
47
+ - !ruby/object:Gem::Dependency
48
+ name: aranha-parsers
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.7'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.7'
47
61
  - !ruby/object:Gem::Dependency
48
62
  name: eac_ruby_gem_support
49
63
  requirement: !ruby/object:Gem::Requirement
@@ -73,12 +87,16 @@ files:
73
87
  - lib/eac_git.rb
74
88
  - lib/eac_git/executables.rb
75
89
  - lib/eac_git/local.rb
90
+ - lib/eac_git/local/commit.rb
91
+ - lib/eac_git/local/commit/changed_file.rb
92
+ - lib/eac_git/local/commit/diff_tree_line.rb
76
93
  - lib/eac_git/local/dirty_files.rb
77
94
  - lib/eac_git/local/subrepo.rb
78
95
  - lib/eac_git/local/subrepo/config.rb
79
96
  - lib/eac_git/remote.rb
80
97
  - lib/eac_git/remote/ls_result.rb
81
98
  - lib/eac_git/rspec.rb
99
+ - lib/eac_git/rspec/stubbed_git_local_repo.rb
82
100
  - lib/eac_git/version.rb
83
101
  - vendor/git-subrepo/Changes
84
102
  - vendor/git-subrepo/Intro.pod
@@ -283,7 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
283
301
  - !ruby/object:Gem::Version
284
302
  version: '0'
285
303
  requirements: []
286
- rubygems_version: 3.0.6
304
+ rubygems_version: 3.0.9
287
305
  signing_key:
288
306
  specification_version: 4
289
307
  summary: Put here de description.