Module: Canopus::Workspace::GitRemote

Defined in:
lib/canopus/workspace/git_remote.rb

Constant Summary collapse

TRANSFER_PHASES =
%i[pack remote push].freeze

Instance Method Summary collapse

Instance Method Details

#accept_git_credentials ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/canopus/workspace/git_remote.rb', line 57

def accept_git_credentials
  prompt = @palette
  raise Error, "No Git credential prompt is open" unless prompt&.dig(:kind) == :git_credentials

  value = prompt.fetch(:query)
  if prompt[:stage] == :username
    raise Error, "Git username is too long" if value.bytesize > 1_024
    username = value.dup
    value.clear
    self.palette = prompt.merge(stage: username.empty? ? :token : :password, username: username,
      query: +"", secret: true, matches: [])
    return @palette
  end

  raise Error, "Git credential is too long" if value.bytesize > 4_096
  secret = value.dup
  value.clear
  operation, remote, username = prompt.values_at(:operation, :remote, :username)
  self.palette = nil
  credentials = username.to_s.empty? ? Thuban::Remote::Credentials.bearer(token: secret) :
    Thuban::Remote::Credentials.static(username: username, password: secret)
  start_git_transfer(operation, remote, credentials: credentials, prompt_auth: false,
    redactions: [username, secret].compact)
ensure
  secret&.clear
end

#cancel_git_transfer ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/canopus/workspace/git_remote.rb', line 35

def cancel_git_transfer
  state = (@git_transfer_guard ||= Mutex.new).synchronize { @git_transfer_state }
  return false unless state

  state.cancel!
  self.message = "Cancelling Git #{state.operation}…"
  true
end

#close_git ⇒ Object



84
85
86
87
88
89
90
91
# File 'lib/canopus/workspace/git_remote.rb', line 84

def close_git
  state = (@git_transfer_guard ||= Mutex.new).synchronize { @git_transfer_state }
  if state
    state.cancel!
    state.job&.join unless state.job&.equal?(Thread.current)
  end
  super
end

#fetch_git(remote = nil, credentials: nil) ⇒ Object



22
23
24
# File 'lib/canopus/workspace/git_remote.rb', line 22

def fetch_git(remote = nil, credentials: nil)
  start_git_transfer(:fetch, remote, credentials: credentials)
end

#git_remotes ⇒ Object

Raises:



16
17
18
19
20
# File 'lib/canopus/workspace/git_remote.rb', line 16

def git_remotes
  state = git_state
  raise Error, "Not a Git repository" unless state
  state.synchronize { |repository| repository.remotes.transform_keys { |name| name.dup.freeze }.freeze }
end

#git_transfer_progress ⇒ Object



44
45
46
47
# File 'lib/canopus/workspace/git_remote.rb', line 44

def git_transfer_progress
  state = (@git_transfer_guard ||= Mutex.new).synchronize { @git_transfer_state }
  state&.lock&.synchronize { state.progress }
end

#poll_git_changes(now: Process.clock_gettime(Process::CLOCK_MONOTONIC)) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/canopus/workspace/git_remote.rb', line 49

def poll_git_changes(now: Process.clock_gettime(Process::CLOCK_MONOTONIC))
  return if @closed

  super
  poll_git_autofetch(now)
  nil
end

#pull_git(remote = nil, credentials: nil) ⇒ Object

Raises:



26
27
28
29
# File 'lib/canopus/workspace/git_remote.rb', line 26

def pull_git(remote = nil, credentials: nil)
  raise Error, "Save or discard all buffer changes before pulling" if @buffers.values.any?(&:dirty?)
  start_git_transfer(:pull, remote, credentials: credentials)
end

#push_git(remote = nil, credentials: nil) ⇒ Object



31
32
33
# File 'lib/canopus/workspace/git_remote.rb', line 31

def push_git(remote = nil, credentials: nil)
  start_git_transfer(:push, remote, credentials: credentials)
end