chore: add tests, fix swagger
This commit is contained in:
parent
6693ceabcc
commit
dd432d9d4a
19 changed files with 253 additions and 63 deletions
|
@ -23,3 +23,19 @@ jobs:
|
|||
- name: Run Format Check
|
||||
run: |
|
||||
make format
|
||||
|
||||
test:
|
||||
runs-on: docker
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.23.3'
|
||||
|
||||
- name: Run Tests
|
||||
run: |
|
||||
make test-coverage
|
3
Makefile
3
Makefile
|
@ -38,3 +38,6 @@ build-docker:
|
|||
-t ghcr.io/aides-infra/aides-repo-api:${DOCKER_TAG}\
|
||||
.
|
||||
|
||||
test-coverage:
|
||||
go test ./... -v -coverpkg=./... -coverprofile=coverage.out
|
||||
bash scripts/coverage-badge.sh
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# Aides repo API
|
||||
|
||||
[![Go Report Card](https://goreportcard.com/badge/code.alt-gnome.ru/aides-infra/aides-repo-api)](https://goreportcard.com/report/code.alt-gnome.ru/aides-infra/aides-repo-api)
|
||||
[![Go Report Card](https://goreportcard.com/badge/code.alt-gnome.ru/aides-infra/aides-repo-api)](https://goreportcard.com/report/code.alt-gnome.ru/aides-infra/aides-repo-api)
|
||||
|
||||
![Coverage](./coverage-badge.svg)
|
|
@ -8,13 +8,20 @@ import (
|
|||
//
|
||||
// @title Aides Repo API
|
||||
// @description API For Aides repo
|
||||
// @schemes https
|
||||
// @schemes http https
|
||||
//
|
||||
// @license.name GPL-3.0
|
||||
// @license.url https://www.gnu.org/licenses/gpl-3.0-standalone.html
|
||||
//
|
||||
// @tag.name tasks
|
||||
// @tag.description Work with tags
|
||||
//
|
||||
|
||||
// @securityDefinitions.apikey ApiKeyAuth
|
||||
// @in header
|
||||
// @name Authorization
|
||||
// @description Type "Bearer" followed by a space and token.
|
||||
|
||||
func main() {
|
||||
app, err := app.New()
|
||||
if err != nil {
|
||||
|
|
6
coverage-badge.svg
Normal file
6
coverage-badge.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="98" height="20">
|
||||
<rect width="59" height="20" fill="#555"/>
|
||||
<rect x="59" width="39" height="20" fill="#4c1"/>
|
||||
<text x="30" y="14" fill="#fff" font-family="Verdana" font-size="11">coverage</text>
|
||||
<text x="65" y="14" fill="#fff" font-family="Verdana" font-size="11">22.3%</text>
|
||||
</svg>
|
After Width: | Height: | Size: 339 B |
20
docs/docs.go
20
docs/docs.go
|
@ -21,6 +21,11 @@ const docTemplate = `{
|
|||
"paths": {
|
||||
"/tasks": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Create a new task for a specific repository",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
|
@ -67,6 +72,11 @@ const docTemplate = `{
|
|||
},
|
||||
"/tasks/{taskID}/upload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Upload multiple files associated with a specific task ID. Each file must be less than 10MB.",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
|
@ -190,6 +200,14 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"description": "Type \"Bearer\" followed by a space and token.",
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"description": "Work with tags",
|
||||
|
@ -203,7 +221,7 @@ var SwaggerInfo = &swag.Spec{
|
|||
Version: "",
|
||||
Host: "",
|
||||
BasePath: "",
|
||||
Schemes: []string{"https"},
|
||||
Schemes: []string{"http", "https"},
|
||||
Title: "Aides Repo API",
|
||||
Description: "API For Aides repo",
|
||||
InfoInstanceName: "swagger",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"schemes": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"swagger": "2.0",
|
||||
|
@ -15,6 +16,11 @@
|
|||
"paths": {
|
||||
"/tasks": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Create a new task for a specific repository",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
|
@ -61,6 +67,11 @@
|
|||
},
|
||||
"/tasks/{taskID}/upload": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"ApiKeyAuth": []
|
||||
}
|
||||
],
|
||||
"description": "Upload multiple files associated with a specific task ID. Each file must be less than 10MB.",
|
||||
"consumes": [
|
||||
"multipart/form-data"
|
||||
|
@ -184,6 +195,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"ApiKeyAuth": {
|
||||
"description": "Type \"Bearer\" followed by a space and token.",
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"description": "Work with tags",
|
||||
|
|
|
@ -85,6 +85,8 @@ paths:
|
|||
description: Internal server error
|
||||
schema:
|
||||
$ref: '#/definitions/errors.ErrResponse'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Create a new task
|
||||
tags:
|
||||
- tasks
|
||||
|
@ -120,11 +122,20 @@ paths:
|
|||
description: Internal Server Error
|
||||
schema:
|
||||
$ref: '#/definitions/errors.ErrResponse'
|
||||
security:
|
||||
- ApiKeyAuth: []
|
||||
summary: Upload files to a task
|
||||
tags:
|
||||
- tasks
|
||||
schemes:
|
||||
- http
|
||||
- https
|
||||
securityDefinitions:
|
||||
ApiKeyAuth:
|
||||
description: Type "Bearer" followed by a space and token.
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
swagger: "2.0"
|
||||
tags:
|
||||
- description: Work with tags
|
||||
|
|
24
go.mod
24
go.mod
|
@ -4,16 +4,21 @@ go 1.23.3
|
|||
|
||||
require (
|
||||
github.com/caarlos0/env/v11 v11.2.2
|
||||
github.com/cavaliergopher/rpm v1.2.0
|
||||
github.com/go-chi/chi/v5 v5.1.0
|
||||
github.com/go-chi/render v1.0.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/go-co-op/gocron/v2 v2.13.0 // indirect
|
||||
github.com/go-co-op/gocron/v2 v2.13.0
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
|
@ -31,20 +36,19 @@ require (
|
|||
github.com/mattn/go-sqlite3 v1.14.24 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/swaggo/files v1.0.1 // indirect
|
||||
github.com/swaggo/http-swagger v1.3.4 // indirect
|
||||
github.com/swaggo/swag v1.16.4 // indirect
|
||||
github.com/swaggo/http-swagger v1.3.4
|
||||
github.com/swaggo/swag v1.16.4
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
|
||||
golang.org/x/net v0.32.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gorm.io/driver/postgres v1.5.11 // indirect
|
||||
gorm.io/driver/sqlite v1.5.7 // indirect
|
||||
gorm.io/gorm v1.25.12 // indirect
|
||||
gorm.io/driver/postgres v1.5.11
|
||||
gorm.io/driver/sqlite v1.5.7
|
||||
gorm.io/gorm v1.25.12
|
||||
moul.io/zapgorm2 v1.3.0
|
||||
)
|
||||
|
|
23
go.sum
23
go.sum
|
@ -1,15 +1,14 @@
|
|||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.2.1 h1:QsZ4TjvwiMpat6gBCBxEQI0rcS9ehtkKtSpiUnd9N28=
|
||||
github.com/PuerkitoBio/purell v1.2.1/go.mod h1:ZwHcC/82TOaovDi//J/804umJFFmbOHPngi8iYYv/Eo=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/caarlos0/env/v11 v11.2.2 h1:95fApNrUyueipoZN/EhA8mMxiNxrBwDa+oAZrMWl3Kg=
|
||||
github.com/caarlos0/env/v11 v11.2.2/go.mod h1:JBfcdeQiBoI3Zh1QRAWfe+tpiNTmDtcCj/hHHHMx0vc=
|
||||
github.com/cavaliergopher/rpm v1.2.0 h1:s0h+QeVK252QFTolkhGiMeQ1f+tMeIMhGl8B1HUmGUc=
|
||||
github.com/cavaliergopher/rpm v1.2.0/go.mod h1:R0q3vTqa7RUvPofAZYrnjJ63hh2vngjFfphuXiExVos=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw=
|
||||
github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
|
@ -45,20 +44,28 @@ github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK
|
|||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/http-swagger v1.3.4 h1:q7t/XLx0n15H1Q9/tk3Y9L4n210XzJF5WtnDX64a5ww=
|
||||
|
@ -69,6 +76,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
|||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
|
@ -86,6 +95,8 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXy
|
|||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -130,9 +141,9 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -28,6 +28,7 @@ func (c *CreateTaskResponse) Render(w http.ResponseWriter, r *http.Request) erro
|
|||
// @Summary Create a new task
|
||||
// @Description Create a new task for a specific repository
|
||||
// @Tags tasks
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body CreateTaskDTO true "Request body to create a task"
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package taskcontroller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
|
||||
"code.alt-gnome.ru/aides-infra/aides-repo-api/internal/common/errors"
|
||||
commonErrors "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/common/errors"
|
||||
|
||||
"code.alt-gnome.ru/aides-infra/aides-repo-api/internal/logger"
|
||||
"code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/taskservice"
|
||||
)
|
||||
|
@ -25,6 +27,7 @@ func (rd *TaskUploadResponse) Render(w http.ResponseWriter, r *http.Request) err
|
|||
// @Summary Upload files to a task
|
||||
// @Description Upload multiple files associated with a specific task ID. Each file must be less than 10MB.
|
||||
// @Tags tasks
|
||||
// @Security ApiKeyAuth
|
||||
// @Accept multipart/form-data
|
||||
// @Produce json
|
||||
// @Param taskID path string true "Task ID"
|
||||
|
@ -36,7 +39,7 @@ func (rd *TaskUploadResponse) Render(w http.ResponseWriter, r *http.Request) err
|
|||
func (c *TaskController) Upload(w http.ResponseWriter, r *http.Request) {
|
||||
taskID := chi.URLParam(r, "taskID")
|
||||
if taskID == "" {
|
||||
render.Render(w, r, &errors.ErrResponse{
|
||||
render.Render(w, r, &commonErrors.ErrResponse{
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
StatusText: "taskID is required",
|
||||
})
|
||||
|
@ -45,7 +48,7 @@ func (c *TaskController) Upload(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
err := r.ParseMultipartForm(10240 << 20)
|
||||
if err != nil {
|
||||
render.Render(w, r, &errors.ErrResponse{
|
||||
render.Render(w, r, &commonErrors.ErrResponse{
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
StatusText: "Bad Request",
|
||||
})
|
||||
|
@ -55,7 +58,7 @@ func (c *TaskController) Upload(w http.ResponseWriter, r *http.Request) {
|
|||
files := r.MultipartForm.File["files"]
|
||||
for _, fileHeader := range files {
|
||||
if fileHeader.Size > (1024 << 20) {
|
||||
render.Render(w, r, &errors.ErrResponse{
|
||||
render.Render(w, r, &commonErrors.ErrResponse{
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
StatusText: "File too large",
|
||||
})
|
||||
|
@ -72,7 +75,18 @@ func (c *TaskController) Upload(w http.ResponseWriter, r *http.Request) {
|
|||
log.Error("Error while upload task", map[string]interface{}{
|
||||
"err": err,
|
||||
})
|
||||
render.Render(w, r, &errors.ErrResponse{
|
||||
|
||||
var e *taskservice.TooOldError
|
||||
if errors.As(err, &e) {
|
||||
render.Render(w, r, &commonErrors.ErrResponse{
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
StatusText: err.Error(),
|
||||
Err: err,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Render(w, r, &commonErrors.ErrResponse{
|
||||
HTTPStatusCode: http.StatusInternalServerError,
|
||||
StatusText: "Internal Server Error",
|
||||
Err: err,
|
||||
|
@ -86,7 +100,7 @@ func (c *TaskController) Upload(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
if err := render.Render(w, r, &response); err != nil {
|
||||
render.Render(w, r, errors.ErrRender(err))
|
||||
render.Render(w, r, commonErrors.ErrRender(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,13 @@ type RPMFile struct {
|
|||
TaskID int
|
||||
Task Task
|
||||
|
||||
Name string
|
||||
Arch string
|
||||
Filename string
|
||||
|
||||
Name string
|
||||
Arch string
|
||||
Version string
|
||||
Release string
|
||||
Epoch int
|
||||
}
|
||||
|
||||
type TaskStatus int
|
||||
|
|
|
@ -123,13 +123,13 @@ func (s *Service) ForceUpdate() error {
|
|||
for _, el := range tasks {
|
||||
for _, fileInfo := range el.Files {
|
||||
localFilePath := path.Join(
|
||||
strconv.FormatUint(uint64(el.ID), 10), fileInfo.Name,
|
||||
strconv.FormatUint(uint64(el.ID), 10), fileInfo.Filename,
|
||||
)
|
||||
symLink := path.Join(
|
||||
futureRepoPath,
|
||||
fileInfo.Arch,
|
||||
"RPMS.aides",
|
||||
fileInfo.Name,
|
||||
fileInfo.Filename,
|
||||
)
|
||||
targetPath := path.Join("../../../../tasks/", localFilePath)
|
||||
err := createSymlink(targetPath, symLink)
|
||||
|
|
|
@ -23,6 +23,7 @@ func (s *Service) Create(repo string) (*models.Task, error) {
|
|||
RepoID: taskRepo.ID,
|
||||
ALTRepo: altRepo,
|
||||
Type: models.TypeUpsert,
|
||||
Status: models.StatusPending,
|
||||
}
|
||||
|
||||
result := s.db.Create(&task)
|
||||
|
|
11
internal/services/taskservice/errors.go
Normal file
11
internal/services/taskservice/errors.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package taskservice
|
||||
|
||||
import "fmt"
|
||||
|
||||
type TooOldError struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (e TooOldError) Error() string {
|
||||
return fmt.Sprintf("%s is too old!", e.Name)
|
||||
}
|
|
@ -6,13 +6,14 @@ import (
|
|||
"io"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cavaliergopher/rpm"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"code.alt-gnome.ru/aides-infra/aides-repo-api/internal/logger"
|
||||
"code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models"
|
||||
)
|
||||
|
||||
|
@ -22,19 +23,9 @@ type TaskUploadInput struct {
|
|||
Files []*multipart.FileHeader
|
||||
}
|
||||
|
||||
func getRPMArchitecture(filePath string) (string, error) {
|
||||
cmd := exec.Command("rpm", "-qp", "--queryformat", "%{ARCH}", filePath)
|
||||
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("ошибка при выполнении команды rpm: %v", err)
|
||||
}
|
||||
|
||||
arch := strings.TrimSpace(string(output))
|
||||
return arch, nil
|
||||
}
|
||||
|
||||
func (s *Service) Upload(input *TaskUploadInput) error {
|
||||
log := logger.GetLogger()
|
||||
|
||||
taskID, err := strconv.Atoi(input.TaskID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -42,12 +33,11 @@ func (s *Service) Upload(input *TaskUploadInput) error {
|
|||
files := input.Files
|
||||
|
||||
task := models.Task{}
|
||||
result := s.db.Preload("Repo").Where(
|
||||
"id = ?", taskID,
|
||||
).First(&task)
|
||||
/*.Where(
|
||||
"status = ?", models.StatusPending,
|
||||
)*/
|
||||
result := s.db.
|
||||
Preload("Repo").
|
||||
Where("id = ?", taskID).
|
||||
First(&task).
|
||||
Where("status = ?", models.StatusPending)
|
||||
|
||||
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||
return result.Error
|
||||
|
@ -56,17 +46,45 @@ func (s *Service) Upload(input *TaskUploadInput) error {
|
|||
return result.Error
|
||||
}
|
||||
|
||||
currentTask := &models.Task{}
|
||||
result = s.db.
|
||||
Model(&models.GitRepoAltRepoTask{}).
|
||||
Select("tasks.*").
|
||||
Joins("JOIN tasks ON tasks.id = git_repo_alt_repo_tasks.current_task_id").
|
||||
Where(&models.GitRepoAltRepoTask{
|
||||
ALTRepoID: task.ALTRepoID,
|
||||
RepoID: task.RepoID,
|
||||
}).
|
||||
Preload("Files").
|
||||
Limit(1).
|
||||
Find(currentTask)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
log.Debug("", map[string]interface{}{
|
||||
"val": currentTask,
|
||||
})
|
||||
|
||||
localPath := path.Join(input.TaskID)
|
||||
taskFolderPath := path.Join(s.config.GetUploadDir(), "tasks", localPath)
|
||||
err = os.MkdirAll(taskFolderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
shouldCleanTask := true
|
||||
defer func() {
|
||||
if shouldCleanTask {
|
||||
os.RemoveAll(taskFolderPath)
|
||||
}
|
||||
}()
|
||||
|
||||
rpmFiles := []models.RPMFile{}
|
||||
|
||||
for _, fileHeader := range files {
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("can't open fileHeader %w", err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
@ -96,34 +114,56 @@ func (s *Service) Upload(input *TaskUploadInput) error {
|
|||
return err
|
||||
}
|
||||
|
||||
arch, err := getRPMArchitecture(filePath)
|
||||
pkg, err := rpm.Open(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f := models.RPMFile{
|
||||
Name: fileHeader.Filename,
|
||||
Arch: arch,
|
||||
Task: task,
|
||||
Filename: fileHeader.Filename,
|
||||
Name: pkg.Name(),
|
||||
Arch: pkg.Architecture(),
|
||||
Version: pkg.Version(),
|
||||
Release: pkg.Release(),
|
||||
Epoch: pkg.Epoch(),
|
||||
Task: task,
|
||||
}
|
||||
|
||||
if err := s.db.Save(&f).Error; err != nil {
|
||||
return err
|
||||
rpmFiles = append(rpmFiles, f)
|
||||
}
|
||||
|
||||
if currentTask.ID != 0 {
|
||||
groupedByName := make(map[string][]*models.RPMFile)
|
||||
for _, file := range rpmFiles {
|
||||
groupedByName[file.Name] = append(groupedByName[file.Name], &file)
|
||||
}
|
||||
for _, file := range currentTask.Files {
|
||||
groupedByName[file.Name] = append(groupedByName[file.Name], &file)
|
||||
}
|
||||
|
||||
// Символическая ссылка
|
||||
/*
|
||||
targetPath := path.Join("../../../../tasks/", localPath, fileHeader.Filename)
|
||||
symLink := path.Join(s.app.Config.UploadDir, "repo/Sisyphus", arch, "RPMS.aides", fileHeader.Filename)
|
||||
err = createSymlink(targetPath, symLink)
|
||||
if err != nil {
|
||||
return err
|
||||
for name, group := range groupedByName {
|
||||
if len(group) > 1 {
|
||||
result := rpm.Compare(
|
||||
&WrapperRpmVersion{group[0]},
|
||||
&WrapperRpmVersion{group[1]},
|
||||
)
|
||||
|
||||
if result < 1 {
|
||||
return &TooOldError{
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
result = s.db.Create(&rpmFiles)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
task.Status = models.StatusCompleted
|
||||
shouldCleanTask = false
|
||||
|
||||
return s.onTaskComplete(&task)
|
||||
}
|
||||
|
|
11
internal/services/taskservice/utils.go
Normal file
11
internal/services/taskservice/utils.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
package taskservice
|
||||
|
||||
import "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models"
|
||||
|
||||
type WrapperRpmVersion struct {
|
||||
file *models.RPMFile
|
||||
}
|
||||
|
||||
func (c *WrapperRpmVersion) Epoch() int { return c.file.Epoch }
|
||||
func (c *WrapperRpmVersion) Version() string { return c.file.Version }
|
||||
func (c *WrapperRpmVersion) Release() string { return c.file.Release }
|
10
scripts/coverage-badge.sh
Executable file
10
scripts/coverage-badge.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash
|
||||
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
|
||||
cat <<EOF > coverage-badge.svg
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="98" height="20">
|
||||
<rect width="59" height="20" fill="#555"/>
|
||||
<rect x="59" width="39" height="20" fill="#4c1"/>
|
||||
<text x="30" y="14" fill="#fff" font-family="Verdana" font-size="11">coverage</text>
|
||||
<text x="65" y="14" fill="#fff" font-family="Verdana" font-size="11">${COVERAGE}%</text>
|
||||
</svg>
|
||||
EOF
|
Loading…
Reference in a new issue