Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/gitlab.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require 'gitlab/headers/total'
require 'gitlab/paginated_response'
require 'gitlab/file_response'
require 'gitlab/header_response'
require 'gitlab/request'
require 'gitlab/api'
require 'gitlab/client'
Expand Down
20 changes: 20 additions & 0 deletions lib/gitlab/client/repository_files.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ def get_file(project, file_path, ref)
})
end

# Gets a repository file metadata.
#
# @example
# Gitlab.get_file_metadata(42, "README.md", "master")
#
# @param [Integer, String] project The ID or name of a project.
# @param [String] file_path The full path of the file.
# @param [String] ref The name of branch, tag or commit.
# @return [Gitlab::ObjectifiedHash]
def get_file_metadata(project, file_path, ref)
head(
"/projects/#{url_encode project}/repository/files/#{url_encode file_path}",
query: { ref: ref },
format: nil,
parser: proc do |_body, _format|
::Gitlab::HeaderResponse.new
end
)
end

# Creates a new repository file.
#
# @example
Expand Down
50 changes: 50 additions & 0 deletions lib/gitlab/header_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

module Gitlab
class HeaderResponse
GITLAB_HEADER = 'x-gitlab-'

def initialize
@headers = {}
end

def empty?
headers.empty?
end

def to_hash
headers
end
alias to_h to_hash

def method_missing(method, *args, &)
if headers.key?(method)
headers[method]
else
super
end
end

def respond_to_missing?(method, include_private = false)
headers.key?(method) || super
end

def inspect
"#<#{self.class}:#{object_id} #{headers}>"
end

def parse_headers!(headers)
@headers = headers.select { |header, _value| header.include?(GITLAB_HEADER) }
.map { |header, value| { header_key(header) => value[0] } }
.reduce(&:merge)
end

private

attr_reader :headers

def header_key(header)
header.gsub(GITLAB_HEADER, '').tr('-', '_').to_sym
end
end
end
4 changes: 3 additions & 1 deletion lib/gitlab/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ module Gitlab
class Request
include HTTParty

SUPPORTED_METHODS = %i[head get post put patch delete].freeze

format :json
maintain_method_across_redirects true
headers 'Accept' => 'application/json', 'Content-Type' => 'application/x-www-form-urlencoded'
Expand Down Expand Up @@ -39,7 +41,7 @@ def self.decode(response)
raise Error::Parsing, 'The response is not a valid JSON'
end

%w[get post put patch delete].each do |method|
SUPPORTED_METHODS.each do |method|
define_method method do |path, options = {}|
params = options.dup

Expand Down
11 changes: 11 additions & 0 deletions spec/gitlab/client/repository_files_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@
end
end

describe '.get_file_metadata' do
before do
stub_head('/projects/3/repository/files/README%2Emd?ref=master', 'empty')
@file = Gitlab.get_file_metadata(3, 'README.md', 'master')
end

it 'gets the correct resource' do
expect(a_head('/projects/3/repository/files/README%2Emd?ref=master')).to have_been_made
end
end

describe '.create_file' do
let(:api_path) { '/projects/3/repository/files/path' }

Expand Down
51 changes: 51 additions & 0 deletions spec/gitlab/header_response_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Gitlab::HeaderResponse do
subject(:resp) { described_class.new }

let(:headers) do
{
'x-gitlab-blob-size' => ['42'],
'x-gitlab-commit-id' => ['foobar'],
'content-type' => ['application/json']
}
end

describe '.empty?' do
it 'returns false' do
expect(resp).to be_empty
end
end

describe '.to_hash' do
it 'empty hash after init' do
expect(resp.to_hash).to eq({})
end
end

describe '.parse_headers!' do
subject(:resp_with_h) do
resp.parse_headers!(headers)
resp
end

it 'parses headers' do
expect(resp_with_h.to_h).to eq(
{
blob_size: '42',
commit_id: 'foobar'
}
)
end

it 'handles getters' do
expect(resp_with_h.commit_id).to eq('foobar')
end

it 'nonexistant header' do
expect { resp_with_h.expires_in }.to raise_error(NoMethodError)
end
end
end
2 changes: 1 addition & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def load_fixture(name)
Kernel.srand config.seed
end

%i[get post put delete patch].each do |method|
Gitlab::Request::SUPPORTED_METHODS.each do |method|
define_method "stub_#{method}" do |path, fixture, status_code = 200|
stub_request(method, "#{Gitlab.endpoint}#{path}")
.with(headers: { 'PRIVATE-TOKEN' => Gitlab.private_token })
Expand Down