Class: Grack::GitAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/grack/git_adapter.rb

Overview

A wrapper for interacting with Git repositories using the git command line tool.

Constant Summary collapse

READ_SIZE =

The number of bytes to read at a time from IO streams.

32768

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bin_path = 'git') ⇒ GitAdapter

Creates a new instance of this adapter.

Parameters:

  • bin_path (String) (defaults to: 'git')

    the path to use for the Git binary.



18
19
20
21
# File 'lib/grack/git_adapter.rb', line 18

def initialize(bin_path = 'git')
  @repository_path = nil
  @git_path = bin_path
end

Instance Attribute Details

#git_pathObject (readonly, private)

The path to use for running the git utility.



100
101
102
# File 'lib/grack/git_adapter.rb', line 100

def git_path
  @git_path
end

#repository_pathObject

The path to the repository on which to operate.



25
26
27
# File 'lib/grack/git_adapter.rb', line 25

def repository_path
  @repository_path
end

Instance Method Details

The string to prepand before ref advertisements



104
105
106
107
# File 'lib/grack/git_adapter.rb', line 104

def advertisement_prefix(pack_type)
  str = "# service=#{pack_type}\n"
  '%04x' % (str.size + 4) << "#{str}0000"
end

#allow_pull?Boolean

Returns true if pulls should be allowed; otherwise; false.

Returns:

  • (Boolean)

    true if pulls should be allowed; otherwise; false.



91
92
93
# File 'lib/grack/git_adapter.rb', line 91

def allow_pull?
  config('http.uploadpack') != 'false'
end

#allow_push?Boolean

Returns true if pushes should be allowed; otherwise; false.

Returns:

  • (Boolean)

    true if pushes should be allowed; otherwise; false.



85
86
87
# File 'lib/grack/git_adapter.rb', line 85

def allow_push?
  config('http.receivepack') == 'true'
end

#command(cmd, args, io_in, io_out, dir = nil) ⇒ Object (private)

Runs the Git utilty with the given subcommand.

Parameters:

  • cmd (String)

    the Git subcommand to invoke.

  • args (Array<String>)

    additional arguments for the command.

  • io_in (#read, nil)

    a readable, IO-like source of data to write to the Git command.

  • io_out (#write, nil)

    a writable, IO-like sink for output produced by the Git command.

  • dir (String, nil) (defaults to: nil)

    a directory to switch to before invoking the Git command.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/grack/git_adapter.rb', line 130

def command(cmd, args, io_in, io_out, dir = nil)
  cmd = [git_path, cmd] + args
  opts = {:err => :close}
  opts[:chdir] = dir unless dir.nil?
  cmd << opts
  IO.popen(cmd, 'r+b') do |pipe|
    while ! io_in.nil? && chunk = io_in.read(READ_SIZE) do
      pipe.write(chunk)
    end
    pipe.close_write
    while chunk = pipe.read(READ_SIZE) do
      io_out.write(chunk) unless io_out.nil?
    end
  end
end

#config(key) ⇒ String (private)

Returns the value for the given key.

Parameters:

  • key (String)

    a key to look up in the Git repository configuration.

Returns:

  • (String)

    the value for the given key.



113
114
115
116
117
# File 'lib/grack/git_adapter.rb', line 113

def config(key)
  capture_io = StringIO.new
  command('config', ['--local', key], nil, capture_io, repository_path.to_s)
  capture_io.string.chomp
end

#exist?Boolean

Returns true if the repository exists; otherwise, false.

Returns:

  • (Boolean)

    true if the repository exists; otherwise, false.



35
36
37
# File 'lib/grack/git_adapter.rb', line 35

def exist?
  repository_path.exist?
end

#file(path) ⇒ FileStreamer?

Returns an object suitable for use as a Rack response body to provide the content of a file at path.

Parameters:

  • path (Pathname)

    the path to a file within the repository.

Returns:

  • (FileStreamer)

    a Rack response body that can stream the file content at path.

  • (nil)

    if path does not exist.



69
70
71
72
73
# File 'lib/grack/git_adapter.rb', line 69

def file(path)
  full_path = @repository_path + path
  return nil unless full_path.exist?
  FileStreamer.new(full_path)
end

#handle_pack(pack_type, io_in, io_out, opts = {}) ⇒ Object

Process the pack file exchange protocol.

Parameters:

  • pack_type (String)

    the type of pack exchange to perform.

  • io_in (#read)

    a readable, IO-like object providing client input data.

  • io_out (#write)

    a writable, IO-like object sending output data to the client.

  • opts (Hash) (defaults to: {})

    options to pass to the Git adapter’s #handle_pack method.

Options Hash (opts):

  • :advertise_refs (Boolean) — default: false


50
51
52
53
54
55
56
57
58
# File 'lib/grack/git_adapter.rb', line 50

def handle_pack(pack_type, io_in, io_out, opts = {})
  args = %w{--stateless-rpc}
  if opts.fetch(:advertise_refs, false)
    io_out.write(advertisement_prefix(pack_type))
    args << '--advertise-refs'
  end
  args << repository_path.to_s
  command(pack_type.sub(/^git-/, ''), args, io_in, io_out)
end

#update_server_infovoid

This method returns an undefined value.

Triggers generation of data necessary to service Git Basic HTTP clients.



79
80
81
# File 'lib/grack/git_adapter.rb', line 79

def update_server_info
  command('update-server-info', [], nil, nil, repository_path)
end