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
d43bff87
Commit
d43bff87
authored
Mar 22, 2020
by
Ethan Reesor
Committed by
Ethan Reesor
May 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Utilize MVVM for Go module proxy
Implement models, entities, presenters
parent
db35842f
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
171 additions
and
57 deletions
+171
-57
ee/app/models/packages/go_module.rb
ee/app/models/packages/go_module.rb
+40
-0
ee/app/models/packages/go_module_version.rb
ee/app/models/packages/go_module_version.rb
+67
-0
ee/app/presenters/packages/go/module_version_presenter.rb
ee/app/presenters/packages/go/module_version_presenter.rb
+19
-0
ee/lib/api/go_proxy.rb
ee/lib/api/go_proxy.rb
+33
-57
ee/lib/ee/api/entities/go_module_version.rb
ee/lib/ee/api/entities/go_module_version.rb
+12
-0
No files found.
ee/app/models/packages/go_module.rb
0 → 100644
View file @
d43bff87
# frozen_string_literal: true
class
Packages::GoModule
#< ApplicationRecord
SEMVER_TAG_REGEX
=
Regexp
.
new
(
"^
#{
::
Packages
::
GoModuleVersion
::
SEMVER_REGEX
.
source
}
$"
).
freeze
# belongs_to :project
attr_reader
:project
,
:name
,
:path
,
:versions
def
initialize
(
project
,
name
)
@project
=
project
@name
=
name
@path
=
if
@name
==
package_base
''
elsif
@name
.
start_with?
(
package_base
+
'/'
)
@name
[(
package_base
.
length
+
1
)
..
]
else
nil
end
end
def
versions
@versions
||=
project
.
repository
.
tags
.
filter
{
|
tag
|
SEMVER_TAG_REGEX
.
match?
(
tag
.
name
)
&&
!
tag
.
dereferenced_target
.
nil?
}.
map
{
|
tag
|
::
Packages
::
GoModuleVersion
.
new
self
,
tag
}.
filter
{
|
ver
|
ver
.
valid?
}
end
def
find_version
(
name
)
versions
.
filter
{
|
ver
|
ver
.
name
==
name
}.
first
end
private
def
package_base
@package_base
||=
Gitlab
::
Routing
.
url_helpers
.
project_url
(
@project
).
split
(
'://'
,
2
)[
1
]
end
end
ee/app/models/packages/go_module_version.rb
0 → 100644
View file @
d43bff87
# frozen_string_literal: true
class
Packages::GoModuleVersion
#< ApplicationRecord
SEMVER_REGEX
=
/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([-.A-Z0-9]+))?(?:\+([-.A-Z0-9]+))?/i
.
freeze
VERSION_SUFFIX_REGEX
=
/\/v([1-9]\d*)$/i
.
freeze
# belongs_to :mod
attr_reader
:mod
,
:tag
delegate
:name
,
to: :tag
def
initialize
(
mod
,
tag
)
@mod
=
mod
@tag
=
tag
end
def
gomod
return
@gomod
unless
@gomod
.
nil?
blob
=
@mod
.
project
.
repository
.
blob_at
(
tag
.
dereferenced_target
.
sha
,
@mod
.
path
+
'/go.mod'
)
@gomod
=
blob
?
blob
.
data
:
''
end
def
valid?
m
=
gomod
.
split
(
"
\n
"
,
2
).
first
case
major
when
0
,
1
m
==
"module
#{
@mod
.
name
}
"
else
m
==
"module
#{
@mod
.
name
}
/v
#{
major
}
"
end
end
def
major
SEMVER_REGEX
.
match
(
@tag
.
name
)[
1
].
to_i
end
def
minor
SEMVER_REGEX
.
match
(
@tag
.
name
)[
2
].
to_i
end
def
patch
SEMVER_REGEX
.
match
(
@tag
.
name
)[
3
].
to_i
end
def
prerelease
SEMVER_REGEX
.
match
(
@tag
.
name
)[
4
]
end
def
build
SEMVER_REGEX
.
match
(
@tag
.
name
)[
5
]
end
def
files
return
@files
unless
@files
.
nil?
sha
=
@tag
.
dereferenced_target
.
sha
tree
=
@mod
.
project
.
repository
.
tree
(
sha
,
mod
.
path
,
recursive:
true
).
entries
.
filter
{
|
e
|
e
.
file?
}
nested
=
tree
.
filter
{
|
e
|
e
.
name
==
'go.mod'
&&
!
(
mod
.
path
==
''
&&
e
.
path
==
'go.mod'
||
e
.
path
==
mod
.
path
+
'/go.mod'
)
}.
map
{
|
e
|
e
.
path
[
0
..-
7
]
}
@files
=
tree
.
filter
{
|
e
|
!
nested
.
any?
{
|
n
|
e
.
path
.
start_with?
n
}
}
end
def
blob_at
(
path
)
@mod
.
project
.
repository
.
blob_at
(
tag
.
dereferenced_target
.
sha
,
path
).
data
end
end
ee/app/presenters/packages/go/module_version_presenter.rb
0 → 100644
View file @
d43bff87
# frozen_string_literal: true
module
Packages
module
Go
class
ModuleVersionPresenter
def
initialize
(
version
)
@version
=
version
end
def
name
@version
.
name
end
def
time
@version
.
tag
.
dereferenced_target
.
committed_date
end
end
end
end
\ No newline at end of file
ee/lib/api/go_proxy.rb
View file @
d43bff87
...
@@ -3,113 +3,89 @@ module API
...
@@ -3,113 +3,89 @@ module API
class
GoProxy
<
Grape
::
API
class
GoProxy
<
Grape
::
API
helpers
::
API
::
Helpers
::
PackagesHelpers
helpers
::
API
::
Helpers
::
PackagesHelpers
SEMVER_REGEX
=
/v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(-[-.A-Z0-9]+)?(\+[-.A-Z0-9]+)?/i
.
freeze
MODULE_VERSION_REQUIREMENTS
=
{
:module_version
=>
::
Packages
::
GoModuleVersion
::
SEMVER_REGEX
}
SEMVER_TAG_REGEX
=
Regexp
.
new
(
"^
#{
SEMVER_REGEX
.
source
}
$"
).
freeze
MODULE_VERSION_REQUIREMENTS
=
{
:module_version
=>
SEMVER_REGEX
}
helpers
do
helpers
do
def
project_package_base
def
find_module
@project_package_base
||=
Gitlab
::
Routing
.
url_helpers
.
project_url
(
user_project
).
split
(
'://'
,
2
)[
1
]
end
def
check_module_name
module_name
=
params
[
:module_name
].
gsub
(
/![[:alpha:]]/
)
{
|
s
|
s
[
1
..
].
upcase
}
module_name
=
params
[
:module_name
].
gsub
(
/![[:alpha:]]/
)
{
|
s
|
s
[
1
..
].
upcase
}
bad_request!
(
'Module Name'
)
if
module_name
.
blank?
bad_request!
(
'Module Name'
)
if
module_name
.
blank?
if
module_name
==
project_package_base
mod
=
::
Packages
::
GoModule
.
new
user_project
,
module_name
[
module_name
,
''
]
not_found!
if
mod
.
path
.
nil?
elsif
module_name
.
start_with?
(
project_package_base
+
'/'
)
[
module_name
,
module_name
[(
project_package_base
.
length
+
1
)
..
]]
else
not_found!
end
end
def
module_version?
(
project
,
path
,
module_name
,
tag
)
return
false
unless
SEMVER_TAG_REGEX
.
match?
(
tag
.
name
)
return
false
unless
tag
.
dereferenced_target
gomod
=
project
.
repository
.
blob_at
(
tag
.
dereferenced_target
.
sha
,
path
+
'/go.mod'
)
mod
return
false
unless
gomod
mod
=
gomod
.
data
.
split
(
"
\n
"
,
2
).
first
mod
==
'module '
+
module_name
end
def
module_versions
(
project
,
path
,
module_name
)
project
.
repository
.
tags
.
filter
{
|
tag
|
module_version?
(
project
,
path
,
module_name
,
tag
)
}
end
end
end
end
params
do
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
requires
:id
,
type:
String
,
desc:
'The ID of a project'
requires
:module_name
,
type:
String
,
desc:
'Module name'
end
end
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
namespace
':id/packages/go/*module_name/@v'
do
namespace
':id/packages/go/*module_name/@v'
do
before
do
end
desc
'Get all tagged versions for a given Go module'
do
desc
'Get all tagged versions for a given Go module'
do
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/list'
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/list'
end
end
get
'list'
do
get
'list'
do
mod
ule_name
,
path
=
check_module_nam
e
mod
=
find_modul
e
content_type
'text/plain'
content_type
'text/plain'
mod
ule_versions
(
user_project
,
path
,
module_name
)
.
map
{
|
t
|
t
.
name
}.
join
(
"
\n
"
)
mod
.
versions
.
map
{
|
t
|
t
.
name
}.
join
(
"
\n
"
)
end
end
desc
'Get information about the given module version'
do
desc
'Get information about the given module version'
do
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.info'
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.info'
success
EE
::
API
::
Entities
::
GoModuleVersion
end
params
do
requires
:module_version
,
type:
String
,
desc:
'Module version'
end
end
get
':module_version.info'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
get
':module_version.info'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
mod
ule_name
,
path
=
check_module_nam
e
mod
=
find_modul
e
tag
=
user_project
.
repository
.
tags
.
filter
{
|
tag
|
tag
.
name
==
params
[
:module_version
]
}.
first
ver
=
mod
.
find_version
params
[
:module_version
]
not_found!
unless
tag
&&
module_version?
(
user_project
,
path
,
module_name
,
tag
)
not_found!
unless
ver
{
present
::
Packages
::
Go
::
ModuleVersionPresenter
.
new
(
ver
),
with:
EE
::
API
::
Entities
::
GoModuleVersion
"Version"
=>
tag
.
name
,
"Time"
=>
tag
.
dereferenced_target
.
committed_date
}
end
end
desc
'Get the module file of the given module version'
do
desc
'Get the module file of the given module version'
do
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.mod'
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.mod'
end
end
params
do
requires
:module_version
,
type:
String
,
desc:
'Module version'
end
get
':module_version.mod'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
get
':module_version.mod'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
mod
ule_name
,
path
=
check_module_nam
e
mod
=
find_modul
e
tag
=
user_project
.
repository
.
tags
.
filter
{
|
tag
|
tag
.
name
==
params
[
:module_version
]
}.
first
ver
=
mod
.
find_version
params
[
:module_version
]
not_found!
unless
tag
&&
module_version?
(
user_project
,
path
,
module_name
,
tag
)
not_found!
unless
ver
content_type
'text/plain'
content_type
'text/plain'
user_project
.
repository
.
blob_at
(
tag
.
dereferenced_target
.
sha
,
path
+
'/go.mod'
).
data
ver
.
gomod
end
end
desc
'Get a zip of the source of the given module version'
do
desc
'Get a zip of the source of the given module version'
do
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.zip'
detail
'See `go help goproxy`, GET $GOPROXY/<module>/@v/<version>.zip'
end
end
params
do
requires
:module_version
,
type:
String
,
desc:
'Module version'
end
get
':module_version.zip'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
get
':module_version.zip'
,
:requirements
=>
MODULE_VERSION_REQUIREMENTS
do
module_name
,
path
=
check_module_name
mod
=
find_module
tag
=
user_project
.
repository
.
tags
.
filter
{
|
tag
|
tag
.
name
==
params
[
:module_version
]
}.
first
not_found!
unless
tag
&&
module_version?
(
user_project
,
path
,
module_name
,
tag
)
sha
=
tag
.
dereferenced_target
.
sha
ver
=
mod
.
find_version
params
[
:module_version
]
tree
=
user_project
.
repository
.
tree
(
sha
,
path
,
recursive:
true
).
entries
.
filter
{
|
e
|
e
.
type
==
:blob
}
not_found!
unless
ver
nested
=
tree
.
filter
{
|
e
|
e
.
name
==
'go.mod'
&&
!
(
path
==
''
&&
e
.
path
==
'go.mod'
||
e
.
path
==
path
+
'/go.mod'
)
}.
map
{
|
e
|
e
.
path
[
0
..-
7
]
}
files
=
tree
.
filter
{
|
e
|
!
nested
.
any?
{
|
n
|
e
.
path
.
start_with?
n
}
}
s
=
Zip
::
OutputStream
.
write_buffer
do
|
zip
|
s
=
Zip
::
OutputStream
.
write_buffer
do
|
zip
|
files
.
each
do
|
file
|
ver
.
files
.
each
do
|
file
|
zip
.
put_next_entry
(
file
.
path
)
zip
.
put_next_entry
file
.
path
zip
.
write
user_project
.
repository
.
blob_at
(
sha
,
file
.
path
).
data
zip
.
write
ver
.
blob_at
(
file
.
path
)
end
end
end
end
header
[
'Content-Disposition'
]
=
ActionDispatch
::
Http
::
ContentDisposition
.
format
(
disposition:
'attachment'
,
filename:
tag
.
name
+
'.zip'
)
header
[
'Content-Disposition'
]
=
ActionDispatch
::
Http
::
ContentDisposition
.
format
(
disposition:
'attachment'
,
filename:
ver
.
name
+
'.zip'
)
header
[
'Content-Transfer-Encoding'
]
=
'binary'
header
[
'Content-Transfer-Encoding'
]
=
'binary'
content_type
'text/plain'
content_type
'text/plain'
# content_type 'application/zip'
# content_type 'application/zip'
...
...
ee/lib/ee/api/entities/go_module_version.rb
0 → 100644
View file @
d43bff87
# frozen_string_literal: true
module
EE
module
API
module
Entities
class
GoModuleVersion
<
Grape
::
Entity
expose
:name
,
as:
'Version'
expose
:time
,
as:
'Time'
end
end
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