mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-04 11:57:35 +00:00
e23fe79e5e
extends the current license detection to support two modes: - legacy which is using classification and was expanded to handle more paths (extensions, different spelling or GNU copying file) - REUSE which avoids classification by relying on the spec dictating that license must be named as SPDX-ID.extension. Newly created repositories will default to REUSE based paths Use of styles at the same time is not allowed by design. Extends the UI to show all the detected licenses and paths to them, deduplicating them per SPDX-ID in database as is in github closes: https://github.com/go-gitea/gitea/issues/28672 --------- Assisted-By: omp:glm5.2 Assisted-By: omp:mimo-v2.5-pro Assisted-By: omp:mimimax-m3 Assisted-By: omp:kimi-k3 Assisted-By: omp:deepseek-v4-flash Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
151 lines
6.3 KiB
Markdown
151 lines
6.3 KiB
Markdown
# Backend development guidelines
|
|
|
|
This document covers backend-specific architecture and contribution expectations.
|
|
For the general workflow see [CONTRIBUTING.md](../CONTRIBUTING.md), and for building
|
|
and testing see [development.md](development.md) and [testing.md](testing.md).
|
|
|
|
## Background
|
|
|
|
The backend is written in Go. Web routing is handled by
|
|
[chi](https://github.com/go-chi/chi) and database access goes through the
|
|
[XORM](https://xorm.io/) ORM. Understanding how the packages depend on each other is
|
|
essential before contributing backend code.
|
|
|
|
## Package design
|
|
|
|
### Package layout
|
|
|
|
The backend is split into top-level packages, each with a focused responsibility:
|
|
|
|
- `build`: helper scripts used at compile time
|
|
- `cmd`: subcommands such as `web`, `serv`, `hooks`, `doctor`, and admin utilities
|
|
- `models`: data structures and database operations (XORM); keeps external
|
|
dependencies to a minimum
|
|
- `models/db`: core database operations
|
|
- `models/fixtures`: sample data used by tests
|
|
- `modelmigration`: schema migration scripts
|
|
- `modules`: standalone functionality with few dependencies
|
|
- `modules/setting`: configuration handling
|
|
- `modules/git`: interaction with the Git command line
|
|
- `routers`: request handlers, split into `api`, `web`, `install`, and `private`
|
|
- `services`: business logic that ties routers and models together
|
|
- `templates`: Go HTML templates
|
|
- `public`: compiled frontend assets
|
|
- `tests`: integration and end-to-end test helpers
|
|
|
|
### Dependency direction
|
|
|
|
Dependencies only flow in one direction:
|
|
|
|
```text
|
|
cmd → routers → services → models → modules
|
|
```
|
|
|
|
A package on the left may import a package on its right, but never the reverse.
|
|
|
|
### Naming conventions
|
|
|
|
- Top-level packages use the plural form: `services`, `models`, `routers`.
|
|
- Subpackages use the singular form: `services/user`, `models/repository`.
|
|
|
|
When packages from different layers share a name, use a snake_case import alias to
|
|
disambiguate:
|
|
|
|
```go
|
|
import user_service "gitea.dev/services/user"
|
|
```
|
|
|
|
### Database transactions
|
|
|
|
Operations that must roll back together should run inside `db.WithTx()` (or
|
|
`db.WithTx2()` when a value must be returned), defined in `models/db/context.go`.
|
|
Functions that participate in a transaction take a `context.Context` as their first
|
|
parameter so the transaction can be propagated.
|
|
|
|
### XORM gotchas
|
|
|
|
- Never call `x.Update(exemplar)` without an explicit `WHERE` clause — it updates
|
|
every row in the table.
|
|
- Partial table migrations must use `SyncWithOptions(IgnoreDrop...)` rather than a
|
|
plain `Sync`.
|
|
- When inserting rows with preset IDs, MSSQL requires `SET IDENTITY_INSERT` to be
|
|
enabled and PostgreSQL requires the sequence to be updated afterwards.
|
|
|
|
## Dependencies
|
|
|
|
Go dependencies are managed with [Go Modules](https://go.dev/ref/mod).
|
|
|
|
Pull requests should only modify `go.mod` and `go.sum` where it relates to the
|
|
change at hand, be it a bug fix or a new feature. Otherwise, these files should only
|
|
be touched by pull requests whose sole purpose is updating dependencies. Run
|
|
`make tidy` after any change to `go.mod`.
|
|
|
|
Any `go.mod` / `go.sum` update must be justified in the PR description and must be
|
|
verified by reviewers and the merger to reference an existing upstream commit.
|
|
|
|
## Golang HTML template
|
|
|
|
Gitea uses Go's built-in HTML template engine which is dynamically & weakly typed.
|
|
To make template code maintainable:
|
|
|
|
- Go code should take over complex logic and prepare template data as much as possible, templates only render the data.
|
|
- Prefer struct types provided by Go code instead of map types for template data.
|
|
- Avoid using single world names for non-local variables.
|
|
- Avoid passing `"root" $` or `"." .` to sub-templates, instead pass the specific data needed by the sub-template.
|
|
- Use explicit variable names instead of `.` to access data: ``{{range $item := $.TargetItems}}{{ $item.Name }}{{end}}``
|
|
- Use Go code to implement render helpers if the render logic is too complex.
|
|
|
|
Using a modern and statically & strongly typed template engine to replace Golang HTML template might be good,
|
|
but the challenge is huge, the requisites are:
|
|
|
|
- A working and maintainable proof-of-concept for the most complex templates (like "PR View" and "PR Diff").
|
|
- A firm commitment of sufficient engineering resources.
|
|
|
|
## API v1
|
|
|
|
The API is documented with [Swagger](https://gitea.com/api/swagger) and is modelled
|
|
on [the GitHub API](https://docs.github.com/en/rest).
|
|
|
|
### GitHub API compatibility
|
|
|
|
Gitea's API should use the same endpoints and fields as the GitHub API where
|
|
possible, unless there is a good reason to deviate.
|
|
|
|
- If Gitea offers functionality GitHub does not, a new endpoint may be added.
|
|
- If Gitea exposes information the GitHub API does not, a new field may be added as
|
|
long as it does not collide with a GitHub field.
|
|
- Existing fields should not be removed unless there is a strong reason; the same
|
|
applies to status responses.
|
|
|
|
If you notice a problem that would require a breaking change, leave a comment in the
|
|
code for a future refactor to API v2 (which is currently not planned) rather than
|
|
breaking v1.
|
|
|
|
### Adding and maintaining API routes
|
|
|
|
- All possible results (errors, success, and failure messages) must be documented in
|
|
the swagger comments on the route.
|
|
- Every JSON request body must be defined as a struct in `modules/structs/` and
|
|
registered in [`routers/api/v1/swagger/options.go`](../routers/api/v1/swagger/options.go).
|
|
- Every JSON response must be defined as a struct in `modules/structs/` and
|
|
registered with its category under [`routers/api/v1/swagger/`](../routers/api/v1/swagger).
|
|
|
|
### HTTP methods and status codes
|
|
|
|
In general, choose HTTP methods as follows:
|
|
|
|
- **GET** returns the requested object(s) with status **200 OK**.
|
|
- **POST** creates a new object (e.g. a user) and returns **201 Created** with the
|
|
created object.
|
|
- **PUT** adds or assigns an existing object (e.g. a user to a team) and returns
|
|
**204 No Content** with no response body.
|
|
- **PATCH** edits an existing object and returns the changed object with **200 OK**.
|
|
- **DELETE** removes an object and returns **204 No Content** with no body.
|
|
|
|
### Requirements for API routes
|
|
|
|
- All parameters of endpoints that edit an object must be optional, except those
|
|
needed to identify the object, which are required.
|
|
- Endpoints returning lists must support pagination (`page` and `limit` query
|
|
options) and set the `X-Total-Count` header via `ctx.SetTotalCountHeader(...)`.
|