Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
0e6f639a
Commit
0e6f639a
authored
Nov 19, 2019
by
Ethan Reesor
Committed by
Stan Hu
Nov 19, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support go-source meta tag for godoc.org
parent
5e60ca15
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
24 deletions
+71
-24
changelogs/unreleased/31397-go-get-meta-source.yml
changelogs/unreleased/31397-go-get-meta-source.yml
+5
-0
doc/user/project/index.md
doc/user/project/index.md
+8
-3
lib/gitlab/middleware/go.rb
lib/gitlab/middleware/go.rb
+18
-12
spec/lib/gitlab/middleware/go_spec.rb
spec/lib/gitlab/middleware/go_spec.rb
+40
-9
No files found.
changelogs/unreleased/31397-go-get-meta-source.yml
0 → 100644
View file @
0e6f639a
---
title
:
Support go-source meta tag for godoc.org
merge_request
:
19888
author
:
Ethan Reesor (@firelizzard)
type
:
changed
doc/user/project/index.md
View file @
0e6f639a
...
...
@@ -200,9 +200,14 @@ When [renaming a user](../profile/index.md#changing-your-username),
## Use your project as a Go package
Any project can be used as a Go package including private projects in subgroups. To use packages
hosted in private projects with the
`go get`
command, use a
[
`.netrc` file
](
https://ec.haxx.se/usingcurl-netrc.html
)
and a
[
personal access token
](
../profile/personal_access_tokens.md
)
in the password field.
Any project can be used as a Go package including private projects in subgroups.
GitLab responds correctly to
`go get`
and
`godoc.org`
discovery requests,
including the
[
`go-import`
](
https://golang.org/cmd/go/#hdr-Remote_import_paths
)
and
[
`go-source`
](
https://github.com/golang/gddo/wiki/Source-Code-Links
)
meta
tags, respectively. To use packages hosted in private projects with the
`go get`
command, use a
[
`.netrc` file
](
https://ec.haxx.se/usingcurl-netrc.html
)
and a
[
personal access token
](
../profile/personal_access_tokens.md
)
in the password
field.
For example:
...
...
lib/gitlab/middleware/go.rb
View file @
0e6f639a
...
...
@@ -25,13 +25,13 @@ module Gitlab
def
render_go_doc
(
request
)
return
unless
go_request?
(
request
)
path
=
project_path
(
request
)
path
,
branch
=
project_path
(
request
)
return
unless
path
body
=
go_body
(
pat
h
)
body
,
code
=
go_response
(
path
,
branc
h
)
return
unless
body
response
=
Rack
::
Response
.
new
(
body
,
200
,
{
'Content-Type'
=>
'text/html'
})
response
=
Rack
::
Response
.
new
(
body
,
code
,
{
'Content-Type'
=>
'text/html'
})
response
.
finish
end
...
...
@@ -39,8 +39,15 @@ module Gitlab
request
[
"go-get"
].
to_i
==
1
&&
request
.
env
[
"PATH_INFO"
].
present?
end
def
go_
body
(
pat
h
)
def
go_
response
(
path
,
branc
h
)
config
=
Gitlab
.
config
body_tag
=
content_tag
:body
,
"go get
#{
config
.
gitlab
.
url
}
/
#{
path
}
"
unless
branch
html_tag
=
content_tag
:html
,
body_tag
return
html_tag
,
404
end
project_url
=
Gitlab
::
Utils
.
append_path
(
config
.
gitlab
.
url
,
path
)
import_prefix
=
strip_url
(
project_url
.
to_s
)
...
...
@@ -52,9 +59,11 @@ module Gitlab
"
#{
project_url
}
.git"
end
meta_tag
=
tag
:meta
,
name:
'go-import'
,
content:
"
#{
import_prefix
}
git
#{
repository_url
}
"
head_tag
=
content_tag
:head
,
meta_tag
content_tag
:html
,
head_tag
meta_import_tag
=
tag
:meta
,
name:
'go-import'
,
content:
"
#{
import_prefix
}
git
#{
repository_url
}
"
meta_source_tag
=
tag
:meta
,
name:
'go-source'
,
content:
"
#{
import_prefix
}
#{
project_url
}
#{
project_url
}
/tree/
#{
branch
}
{/dir}
#{
project_url
}
/blob/
#{
branch
}
{/dir}/{file}#L{line}"
head_tag
=
content_tag
:head
,
meta_import_tag
+
meta_source_tag
html_tag
=
content_tag
:html
,
head_tag
+
body_tag
[
html_tag
,
200
]
end
def
strip_url
(
url
)
...
...
@@ -80,9 +89,6 @@ module Gitlab
path_segments
=
path
.
split
(
'/'
)
simple_project_path
=
path_segments
.
first
(
2
).
join
(
'/'
)
# If the path is at most 2 segments long, it is a simple `namespace/project` path and we're done
return
simple_project_path
if
path_segments
.
length
<=
2
project_paths
=
[]
begin
project_paths
<<
path_segments
.
join
(
'/'
)
...
...
@@ -94,7 +100,7 @@ module Gitlab
if
project
# If a project is found and the user has access, we return the full project path
project
.
full_pat
h
return
project
.
full_path
,
project
.
default_branc
h
else
# If not, we return the first two components as if it were a simple `namespace/project` path,
# so that we don't reveal the existence of a nested project the user doesn't have access to.
...
...
@@ -105,7 +111,7 @@ module Gitlab
# `go get gitlab.com/group/subgroup/project/subpackage` will not work for private projects.
# `go get gitlab.com/group/subgroup/project.git/subpackage` will work, since Go is smart enough
# to figure that out. `import 'gitlab.com/...'` behaves the same as `go get`.
simple_project_path
return
simple_project_path
,
'master'
end
end
...
...
spec/lib/gitlab/middleware/go_spec.rb
View file @
0e6f639a
...
...
@@ -30,13 +30,13 @@ describe Gitlab::Middleware::Go do
shared_examples
'go-get=1'
do
|
enabled_protocol
:|
context
'with simple 2-segment project path'
do
let!
(
:project
)
{
create
(
:project
,
:private
)
}
let!
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
context
'with subpackages'
do
let
(
:path
)
{
"
#{
project
.
full_path
}
/subpackage"
}
it
'returns the full project path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
)
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
,
project
.
default_branch
)
end
end
...
...
@@ -44,19 +44,19 @@ describe Gitlab::Middleware::Go do
let
(
:path
)
{
project
.
full_path
}
it
'returns the full project path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
)
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
,
project
.
default_branch
)
end
end
end
context
'with a nested project path'
do
let
(
:group
)
{
create
(
:group
,
:nested
)
}
let!
(
:project
)
{
create
(
:project
,
:public
,
namespace:
group
)
}
let!
(
:project
)
{
create
(
:project
,
:public
,
:repository
,
namespace:
group
)
}
shared_examples
'a nested project'
do
context
'when the project is public'
do
it
'returns the full project path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
)
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
,
project
.
default_branch
)
end
end
...
...
@@ -67,7 +67,7 @@ describe Gitlab::Middleware::Go do
shared_examples
'unauthorized'
do
it
'returns the 2-segment group path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
group
.
full_path
)
expect_response_with_path
(
go
,
enabled_protocol
,
group
.
full_path
,
project
.
default_branch
)
end
end
...
...
@@ -85,7 +85,7 @@ describe Gitlab::Middleware::Go do
shared_examples
'authenticated'
do
context
'with access to the project'
do
it
'returns the full project path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
)
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
,
project
.
default_branch
)
end
end
...
...
@@ -160,6 +160,36 @@ describe Gitlab::Middleware::Go do
go
end
end
context
'with a public project without a repository'
do
let!
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:path
)
{
project
.
full_path
}
it
'returns 404'
do
response
=
go
expect
(
response
[
0
]).
to
eq
(
404
)
expect
(
response
[
1
][
'Content-Type'
]).
to
eq
(
'text/html'
)
expected_body
=
%{<html><body>go get #{Gitlab.config.gitlab.url}/#{project.full_path}</body></html>}
expect
(
response
[
2
].
body
).
to
eq
([
expected_body
])
end
end
context
'with a non-standard head'
do
let
(
:user
)
{
create
(
:user
)
}
let!
(
:project
)
{
create
(
:project
,
:public
,
:repository
)
}
let
(
:path
)
{
project
.
full_path
}
let
(
:default_branch
)
{
'default_branch'
}
before
do
project
.
add_maintainer
(
user
)
project
.
repository
.
add_branch
(
user
,
default_branch
,
'master'
)
project
.
change_head
(
default_branch
)
end
it
'returns the full project path'
do
expect_response_with_path
(
go
,
enabled_protocol
,
project
.
full_path
,
default_branch
)
end
end
end
context
'with SSH disabled'
do
...
...
@@ -199,16 +229,17 @@ describe Gitlab::Middleware::Go do
middleware
.
call
(
env
)
end
def
expect_response_with_path
(
response
,
protocol
,
path
)
def
expect_response_with_path
(
response
,
protocol
,
path
,
branch
)
repository_url
=
case
protocol
when
:ssh
"ssh://
#{
Gitlab
.
config
.
gitlab
.
user
}
@
#{
Gitlab
.
config
.
gitlab
.
host
}
/
#{
path
}
.git"
when
:http
,
nil
"http://
#{
Gitlab
.
config
.
gitlab
.
host
}
/
#{
path
}
.git"
end
project_url
=
"http://
#{
Gitlab
.
config
.
gitlab
.
host
}
/
#{
path
}
"
expect
(
response
[
0
]).
to
eq
(
200
)
expect
(
response
[
1
][
'Content-Type'
]).
to
eq
(
'text/html'
)
expected_body
=
%{<html><head><meta name="go-import" content="#{Gitlab.config.gitlab.host}/#{path} git #{repository_url}" /><
/head
></html>}
expected_body
=
%{<html><head><meta name="go-import" content="#{Gitlab.config.gitlab.host}/#{path} git #{repository_url}" /><
meta name="go-source" content="#{Gitlab.config.gitlab.host}/#{path} #{project_url} #{project_url}/tree/#{branch}{/dir} #{project_url}/blob/#{branch}{/dir}/{file}#L{line}" /></head><body>go get #{Gitlab.config.gitlab.url}/#{path}</body
></html>}
expect
(
response
[
2
].
body
).
to
eq
([
expected_body
])
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment