Class: Dapp::Dimg::GitRepo::Base

Inherits:
Object
  • Object
show all
Includes:
Helper::Trivia
Defined in:
lib/dapp/dimg/git_repo/base.rb

Overview

Base class for any Git repo (remote, gitkeeper, etc)

Direct Known Subclasses

Local, Remote

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper::Trivia

#check_path?, #check_subpath?, #class_to_lowercase, class_to_lowercase, #delete_file, #ignore_path?, #ignore_path_base, #kwargs, #make_path, #path_checker, #search_file_upward

Constructor Details

#initialize(dapp, name) ⇒ Base

Returns a new instance of Base.



11
12
13
14
# File 'lib/dapp/dimg/git_repo/base.rb', line 11

def initialize(dapp, name)
  @dapp = dapp
  @name = name
end

Instance Attribute Details

#dappObject (readonly)

Returns the value of attribute dapp.



9
10
11
# File 'lib/dapp/dimg/git_repo/base.rb', line 9

def dapp
  @dapp
end

#nameObject (readonly)

Returns the value of attribute name.



8
9
10
# File 'lib/dapp/dimg/git_repo/base.rb', line 8

def name
  @name
end

Instance Method Details

#blobs_entries(commit, paths: [], exclude_paths: []) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/dapp/dimg/git_repo/base.rb', line 113

def blobs_entries(commit, paths: [], exclude_paths: [])
  [].tap do |entries|
    lookup_commit(commit).tree.walk_blobs(:preorder) do |root, entry|
      fullpath = File.join(root, entry[:name]).reverse.chomp('/').reverse
      next if ignore_path?(fullpath, paths: paths, exclude_paths: exclude_paths)
      entries << [root, entry]
    end
  end
end

#branchObject



141
142
143
144
145
# File 'lib/dapp/dimg/git_repo/base.rb', line 141

def branch
  git.head.name.sub(/^refs\/heads\//, '')
rescue Rugged::ReferenceError => e
  raise Error::Rugged, code: :git_repository_reference_error, data: { name: name, message: e.message.downcase }
end

#commit_exists?(commit) ⇒ Boolean

Returns:

  • (Boolean)


133
134
135
# File 'lib/dapp/dimg/git_repo/base.rb', line 133

def commit_exists?(commit)
  git.exists?(commit)
end

#diff(from, to, **kwargs) ⇒ Object



123
124
125
126
127
128
129
130
131
# File 'lib/dapp/dimg/git_repo/base.rb', line 123

def diff(from, to, **kwargs)
  if to.nil?
    raise "Workdir diff not supported for #{self.class}"
  elsif from.nil?
    Rugged::Tree.diff(git, nil, to, **kwargs)
  else
    lookup_commit(from).diff(lookup_commit(to), **kwargs)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/dapp/dimg/git_repo/base.rb', line 179

def empty?
  git.empty?
end

#exclude_pathsObject



16
17
18
# File 'lib/dapp/dimg/git_repo/base.rb', line 16

def exclude_paths
  []
end

#find_commit_id_by_message(regex) ⇒ Object



158
159
160
161
162
163
# File 'lib/dapp/dimg/git_repo/base.rb', line 158

def find_commit_id_by_message(regex)
  walker.each do |commit|
    msg = commit.message.encode('UTF-8', invalid: :replace, undef: :replace)
    return commit.oid if msg =~ regex
  end
end

#ignore_patch?(patch, paths: [], exclude_paths: []) ⇒ Boolean

Returns:

  • (Boolean)


109
110
111
# File 'lib/dapp/dimg/git_repo/base.rb', line 109

def ignore_patch?(patch, paths: [], exclude_paths: [])
  ignore_path?(patch.delta.new_file[:path], paths: paths, exclude_paths: exclude_paths)
end

#latest_commit(_branch) ⇒ Object



137
138
139
# File 'lib/dapp/dimg/git_repo/base.rb', line 137

def latest_commit(_branch)
  raise
end

#lookup_commit(commit) ⇒ Object



175
176
177
# File 'lib/dapp/dimg/git_repo/base.rb', line 175

def lookup_commit(commit)
  git.lookup(commit)
end

#lookup_object(oid) ⇒ Object



171
172
173
# File 'lib/dapp/dimg/git_repo/base.rb', line 171

def lookup_object(oid)
  git.lookup(oid)
end

#nested_git_directories_patches(*_args) ⇒ Object



47
48
49
# File 'lib/dapp/dimg/git_repo/base.rb', line 47

def nested_git_directories_patches(*_args)
  raise
end

#patches(from, to, paths: [], exclude_paths: [], **kwargs) ⇒ Object

FIXME: Убрать логику исключения путей exclude_paths из данного класса, FIXME: т.к. большинство методов не поддерживают инвариант FIXME “всегда выдавать данные с исключенными путями”. FIXME: Например, метод diff выдает данные без учета exclude_paths. FIXME: Лучше перенести фильтрацию в GitArtifact::diff_patches. FIXME: ИЛИ обеспечить этот инвариант, но это ограничит в возможностях FIXME: использование Rugged извне этого класса и это более сложный путь. FIXME: Лучше сейчас убрать фильтрацию, а добавить ее когда наберется достаточно FIXME: примеров использования.



103
104
105
106
107
# File 'lib/dapp/dimg/git_repo/base.rb', line 103

def patches(from, to, paths: [], exclude_paths: [], **kwargs)
  diff(from, to, **kwargs).patches.select do |patch|
    !ignore_patch?(patch, paths: paths, exclude_paths: exclude_paths)
  end
end

#remote_branchesObject



151
152
153
154
155
156
# File 'lib/dapp/dimg/git_repo/base.rb', line 151

def remote_branches
  git.branches
    .map(&:name)
    .select { |b| b.start_with?('origin/') }
    .map { |b| b.reverse.chomp('origin/'.reverse).reverse }
end

#remote_origin_urlObject



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/dapp/dimg/git_repo/base.rb', line 20

def remote_origin_url
  @remote_origin_url ||= begin
    ro_url = url
    while url_protocol(ro_url) == :noname
      begin
        parent_git = Rugged::Repository.discover(ro_url)
      rescue Rugged::OSError
        parent_git_path = parent_git ? parent_git.path : path
        raise Error::Rugged, code: :git_repository_not_found, data: { path: ro_url, parent_git_path: parent_git_path }
      end

      ro_url = begin
        git_url(parent_git)
      rescue Error::Rugged => e
        break if e.net_status[:code] == :git_repository_without_remote_url # local repository
        raise
      end
    end

    ro_url
  end
end

#remote_origin_url_protocolObject



43
44
45
# File 'lib/dapp/dimg/git_repo/base.rb', line 43

def remote_origin_url_protocol
  url_protocol(remote_origin_url)
end

#submodule_params(submodule) ⇒ Object



56
57
58
59
60
61
62
63
# File 'lib/dapp/dimg/git_repo/base.rb', line 56

def submodule_params(submodule)
  {}.tap do |params|
    params[:path]   = submodule.path
    params[:url]    = submodule_url(submodule.url)
    params[:type]   = url_protocol(params[:url]) == :noname ? :local : :remote
    params[:commit] = submodule.head_oid
  end
end

#submodule_url(gitsubmodule_url) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/dapp/dimg/git_repo/base.rb', line 74

def submodule_url(gitsubmodule_url)
  if gitsubmodule_url.start_with?('../')
    case remote_origin_url_protocol
    when :http, :https, :git
      uri = URI.parse(remote_origin_url)
      uri.path = File.expand_path(File.join(uri.path, gitsubmodule_url))
      uri.to_s
    when :ssh
      host_with_user, group_and_project = remote_origin_url.split(':', 2)
      group_and_project = File.expand_path(File.join('/', group_and_project, gitsubmodule_url))[1..-1]
      [host_with_user, group_and_project].join(':')
    else
      raise
    end
  else
    gitsubmodule_url
  end
end

#submodules(commit, paths: [], exclude_paths: []) ⇒ Object



65
66
67
68
# File 'lib/dapp/dimg/git_repo/base.rb', line 65

def submodules(commit, paths: [], exclude_paths: [])
  Rugged::SubmoduleCollection.new(submodules_git(commit))
    .select { |s| !ignore_directory?(s.path, paths: paths, exclude_paths: exclude_paths) }
end

#submodules_git(_) ⇒ Object



70
71
72
# File 'lib/dapp/dimg/git_repo/base.rb', line 70

def submodules_git(_)
  git
end

#submodules_params(commit, paths: [], exclude_paths: []) ⇒ Object



51
52
53
54
# File 'lib/dapp/dimg/git_repo/base.rb', line 51

def submodules_params(commit, paths: [], exclude_paths: [])
  raise "Workdir not supported for `#{self.class}` repository" if commit.nil?
  submodules(commit, paths: paths, exclude_paths: exclude_paths).map(&method(:submodule_params))
end

#tagsObject



147
148
149
# File 'lib/dapp/dimg/git_repo/base.rb', line 147

def tags
  git.tags.map(&:name)
end

#tracked_remote_repository?Boolean

Returns:

  • (Boolean)


183
184
185
# File 'lib/dapp/dimg/git_repo/base.rb', line 183

def tracked_remote_repository?
  !git.remotes.to_a.empty?
end

#walkerObject



165
166
167
168
169
# File 'lib/dapp/dimg/git_repo/base.rb', line 165

def walker
  walker = Rugged::Walker.new(git)
  walker.push(git.head.target_id)
  walker
end