WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
242 commits
Select commit Hold shift + click to select a range
fdc1331
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
7a3f078
add group model
GamerGirlandCo Dec 25, 2024
b42c752
create GroupList type and methods
GamerGirlandCo Dec 25, 2024
037443c
add `Group` methods and helper functions
GamerGirlandCo Dec 25, 2024
a83db89
add avatar to group
GamerGirlandCo Dec 28, 2024
87dadc1
add `ParentGroup` field and related `LoadParentGroup` method to `Grou…
GamerGirlandCo Dec 28, 2024
01647e2
add `GroupTeam` and `GroupUnit` structs and helpers
GamerGirlandCo Dec 28, 2024
fed2afa
add condition and builder functions to be used when searching for groups
GamerGirlandCo Dec 28, 2024
d120d6c
add `OwnerName` field to `Group` struct
GamerGirlandCo Dec 28, 2024
9444b3b
rename `DisplayName` -> `FullName` for consistency
GamerGirlandCo Dec 28, 2024
b839047
add `IsPrivate` and `Visibility` fields to `Group` struct
GamerGirlandCo Dec 28, 2024
1cd4bf7
add `FindGroupsByCond` helper function
GamerGirlandCo Dec 28, 2024
bcda655
fix nonexistent variable reference in `GetGroupByID` function
GamerGirlandCo Dec 28, 2024
f4836af
add `GroupLink` method to `Group` struct
GamerGirlandCo Dec 28, 2024
f7509f9
add helper functions for dealing with group hierarchies
GamerGirlandCo Dec 28, 2024
58c6f04
refactor subgroup loading, add method to load only groups accessible …
GamerGirlandCo Dec 28, 2024
a07db79
register `GroupTeam` and `GroupUnit` models
GamerGirlandCo Dec 28, 2024
c0cc6de
add condition and builder functions to be used when searching for groups
GamerGirlandCo Dec 28, 2024
e7658b1
changes
GamerGirlandCo Jan 9, 2025
980d86f
update group model
GamerGirlandCo Jan 9, 2025
86413c6
add `UserOrgTeamPermCond` function
GamerGirlandCo Jan 9, 2025
4fbdfb8
add new fields and methods to `GroupTeam` model
GamerGirlandCo Jan 9, 2025
ac0fbd6
update group_unit.go
GamerGirlandCo Jan 9, 2025
fca7dc3
remove unused parameter from `Group.relAvatarLink` method
GamerGirlandCo Jan 9, 2025
54878c3
[models] update repo model
GamerGirlandCo Jan 9, 2025
63bfd8f
update repo_permission.go
GamerGirlandCo Jan 9, 2025
9399511
add conversion functions for repository groups
GamerGirlandCo Jan 9, 2025
65fbdfe
add file with functions relating to organization teams and repo groups
GamerGirlandCo Jan 9, 2025
2ba7b42
update `team_list.go`
GamerGirlandCo Jan 9, 2025
e0ddc36
add group-related url segments to list of reserved usernames
GamerGirlandCo Jan 9, 2025
2e2dd54
[models/search-options] add `GroupID` to `SearchRepoOptions`
GamerGirlandCo Jan 9, 2025
2101a82
[models/conds] add functions returning builders to help find repos ma…
GamerGirlandCo Jan 10, 2025
4c24d88
[models/conds] update some repo conditions to check for access provid…
GamerGirlandCo Jan 10, 2025
57e73fd
[models] update `GetTeamRepositories` to also return repositories acc…
GamerGirlandCo Jan 10, 2025
8c9bce8
[services] ensure `OwnerName` field is updated in groups owned by an …
GamerGirlandCo Jan 10, 2025
6178215
[misc] update avatar utils to handle group avatars
GamerGirlandCo Jan 10, 2025
33d282b
fix duplicate teams being returned by `GetTeamsWithAccessToGroup`
GamerGirlandCo Jul 20, 2025
9611964
fix bug where all repos are returned even when `opts.GroupID` == 0
GamerGirlandCo Jul 20, 2025
95f51ab
remove unused/redundant `IsPrivate` field from Group struct
GamerGirlandCo Aug 11, 2025
f944bc3
add `UpdateGroup` function
GamerGirlandCo Aug 11, 2025
b71eb2a
[services] update `MoveGroupItem` function to set `newPos` to the len…
GamerGirlandCo Aug 11, 2025
f3a8396
add missing nil check before `IsErrGroupNotExist` call
GamerGirlandCo Aug 13, 2025
e3375ea
add test fixtures
GamerGirlandCo Aug 13, 2025
ea9a14b
fix `no columns found to update` error when recalculating group access
GamerGirlandCo Aug 13, 2025
6782dfb
add some unit tests for group service
GamerGirlandCo Aug 13, 2025
ac574bf
fix deadlock caused by differing contexts when retrieving group ances…
GamerGirlandCo Aug 13, 2025
b6b5cb9
add `GroupID` field to `CreateRepoOptions`
GamerGirlandCo Aug 13, 2025
c58dd4d
fix build error caused by changed function name
GamerGirlandCo Aug 13, 2025
9b56464
add `GroupID` and `GroupSortOrder` fields to `Repository` api struct
GamerGirlandCo Aug 13, 2025
f8ab984
fix more build errors
GamerGirlandCo Aug 13, 2025
9d8eea4
add api types for groups
GamerGirlandCo Aug 13, 2025
47ab34d
fix a few more build errors
GamerGirlandCo Aug 13, 2025
dcc2525
regenerate swagger definitions
GamerGirlandCo Aug 13, 2025
10d961d
format files
GamerGirlandCo Aug 13, 2025
05f8eed
reapply changes wiped out by conflict resolution
GamerGirlandCo Aug 13, 2025
8569e3f
add ownership check when moving repository to a new group
GamerGirlandCo Aug 13, 2025
354a983
apply simple linting changes
GamerGirlandCo Aug 13, 2025
1359cf0
apply simple linting changes
GamerGirlandCo Aug 13, 2025
197d3ee
update repo service to check that `GroupID` is owned by the repo owne…
GamerGirlandCo Aug 14, 2025
8a0fed8
move parameters of the `MoveGroup` function into a struct, `MoveGroup…
GamerGirlandCo Aug 14, 2025
bb05c96
rename tables in group-related query conditions
GamerGirlandCo Aug 14, 2025
95c863d
add api routes and functions for repository groups
GamerGirlandCo Aug 14, 2025
93d46c0
add `doer` parameter to `MoveGroupItem` describing the user trying to…
GamerGirlandCo Aug 14, 2025
0d2b94f
update `AccessibleGroupCondition` function to take a minimum `perm.Ac…
GamerGirlandCo Aug 14, 2025
2451cc0
remove bare return
GamerGirlandCo Aug 14, 2025
d3cfd29
run formatter
GamerGirlandCo Aug 14, 2025
6c19946
move group routes that don't depend on the `org` path parameter out o…
GamerGirlandCo Aug 14, 2025
82fe33c
add appropriate swagger definitions
GamerGirlandCo Aug 14, 2025
d6a567f
refactor group creation such that we know the owner ID ahead of time,…
GamerGirlandCo Aug 14, 2025
e7a4d2d
fix swagger definition references to nonexistent `CreateGroupOption`
GamerGirlandCo Aug 14, 2025
e4a09f7
add api routes and functions to get a repository group's subgroups an…
GamerGirlandCo Aug 14, 2025
6b57a9c
fix build errors
GamerGirlandCo Aug 14, 2025
21a56b1
fix build and lint errors
GamerGirlandCo Aug 14, 2025
206e04e
fix failing tests ?
GamerGirlandCo Aug 14, 2025
5c89751
ensure we return early if there was an error loading group units
GamerGirlandCo Aug 16, 2025
0a83c62
fix bug where `builder.In` cond for groups and teams was not placed i…
GamerGirlandCo Aug 16, 2025
7d36de2
remove `UNIQUE` constraint on `Group.LowerName`
GamerGirlandCo Aug 16, 2025
da06c45
add explicit `TEXT` type to `Group.LowerName` tag
GamerGirlandCo Aug 16, 2025
205e0c2
add/remove more constraints for mssql/mysql compatibility
GamerGirlandCo Aug 16, 2025
b870ad2
rename test fixture files for group units and teams
GamerGirlandCo Aug 16, 2025
46f0c8c
fix more failing tests
GamerGirlandCo Aug 16, 2025
f4a5136
add indices to group_id and group_sort_order column
GamerGirlandCo Aug 17, 2025
1293d51
add `AvatarURL` field to api groups (in `modules/structs` package)
GamerGirlandCo Aug 16, 2025
e377f00
update repository storage layout as per https://github.com/go-gitea/g…
GamerGirlandCo Aug 17, 2025
7208ebe
update API routes as well
GamerGirlandCo Aug 17, 2025
8de31c7
fix optional path segments not working out as planned
GamerGirlandCo Aug 18, 2025
ad4177b
update `FullName` method to show group id if it's non-zero
GamerGirlandCo Aug 18, 2025
c62a18a
add group ID column to repository table's unique constraint
GamerGirlandCo Aug 18, 2025
9940611
add group id segment to repository's `Link` method
GamerGirlandCo Aug 18, 2025
2bb4680
fix broken hooks
GamerGirlandCo Aug 18, 2025
636d677
make it more apparent in URLs that a repo is part of a group
GamerGirlandCo Aug 18, 2025
91da404
fix broken hooks (again)
GamerGirlandCo Aug 18, 2025
aea4f49
ensure that repository is moved on disk in `MoveGroupItem` function
GamerGirlandCo Aug 18, 2025
2cfc666
fix moving items to the root-level (`GroupID` <= 0)
GamerGirlandCo Aug 18, 2025
f6c6de5
fix bug where a repo's group id and group sort order are zero in API …
GamerGirlandCo Aug 22, 2025
fcb0e44
ensure visited repo's group owner is the same as the repo's owner, ot…
GamerGirlandCo Aug 22, 2025
8d5a149
chore: update makefile and add new tool
GamerGirlandCo Nov 21, 2025
0f142b8
sync with main
GamerGirlandCo Nov 22, 2025
fa08d70
fix compile errors in migrations
GamerGirlandCo Nov 22, 2025
094ad7e
update `serv` command to recognize group ids in urls
GamerGirlandCo Nov 22, 2025
4c0a4aa
update integration test utilities to tage group id as argument
GamerGirlandCo Nov 22, 2025
bf4b2df
update calls to `GetRepositoryByName` to use new signature
GamerGirlandCo Nov 22, 2025
e98a7ab
update swagger definitions
GamerGirlandCo Nov 22, 2025
0f5ea4e
fix swagger comments in repo adoption routes
GamerGirlandCo Nov 22, 2025
5e98a24
add missing group id parameters to test function calls
GamerGirlandCo Nov 22, 2025
764b63d
run formatter
GamerGirlandCo Nov 22, 2025
39e8696
remove references to `db.DefaultContext`
GamerGirlandCo Nov 22, 2025
408d76f
appease the linter
GamerGirlandCo Nov 22, 2025
09929c4
fix `groupSegmentWithTrailingSlash` to return an empty string if gid …
GamerGirlandCo Nov 22, 2025
6e9c091
update activity actions to return paths/links with a repo's group
GamerGirlandCo Nov 23, 2025
0e0e59a
add trailing newline when generating swagger group routes
GamerGirlandCo Nov 23, 2025
263402e
update v1_groups.json
GamerGirlandCo Nov 23, 2025
12a0ddc
fix wrong group in issue xref test
GamerGirlandCo Nov 23, 2025
60d2bf0
update group swagger definitions
GamerGirlandCo Nov 23, 2025
f5f47ca
fix determinism of repo group swagger output
GamerGirlandCo Nov 23, 2025
06e56b3
fix issue reference regex
GamerGirlandCo Nov 23, 2025
f1d4cd1
move dummy repositories to proper subgroup directories
GamerGirlandCo Nov 23, 2025
7997e49
fix mssql migrations
GamerGirlandCo Nov 23, 2025
0cc4fe8
fix repo url parsing
GamerGirlandCo Nov 23, 2025
e576cf0
add missing repo meta for group unit tests
GamerGirlandCo Nov 23, 2025
3b85107
remove redundant return value from `fillPathParts`
GamerGirlandCo Nov 23, 2025
6bc884b
fix repo url parsing (again)
GamerGirlandCo Nov 23, 2025
b88f6ac
fix moving repos to a different subgroup
GamerGirlandCo Nov 23, 2025
96da292
fix transfers of repos in subgroups
GamerGirlandCo Nov 23, 2025
b2cb082
fix more regex patterns
GamerGirlandCo Nov 23, 2025
28f8ad1
fix failing test in issue_xref_test.go
GamerGirlandCo Nov 24, 2025
c05e38c
fix integration test api urls
GamerGirlandCo Nov 24, 2025
e2c8c05
fix artifact download endpoint urls
GamerGirlandCo Nov 24, 2025
6a23a2e
add missing copyright
GamerGirlandCo Nov 24, 2025
c881888
fix `maybeGroupSegment` func, run formatter
GamerGirlandCo Nov 24, 2025
0b8614f
fix unique constraints for repos and subgroups
GamerGirlandCo Nov 24, 2025
4e1e009
fix helm package test
GamerGirlandCo Nov 24, 2025
1f40523
sync csv test with upstream
GamerGirlandCo Nov 24, 2025
2481bf8
add GroupID field to IssueMeta struct
GamerGirlandCo Nov 24, 2025
e85b918
fix issue dependency tests
GamerGirlandCo Nov 24, 2025
b30ca38
add team-related routes for repos in subgroups
GamerGirlandCo Nov 24, 2025
3614035
fix repository renaming
GamerGirlandCo Nov 24, 2025
fcfef8a
fix more tests
GamerGirlandCo Nov 24, 2025
a0e2808
fix go-get import paths
GamerGirlandCo Nov 24, 2025
ce25276
update swagger definitions
GamerGirlandCo Nov 24, 2025
0397779
fix hook url
GamerGirlandCo Nov 25, 2025
47d8dbf
add missing serv route
GamerGirlandCo Nov 25, 2025
e6f088a
set hooks to be executable
GamerGirlandCo Nov 25, 2025
5c48aa1
reorder serv routes
GamerGirlandCo Nov 25, 2025
24b360d
fix permissions on some test repos
GamerGirlandCo Nov 25, 2025
3243b7a
fix more tests
GamerGirlandCo Nov 25, 2025
34480ad
use a custom ordered map to create group swagger mixin
GamerGirlandCo Nov 26, 2025
207931b
fix repo api url
GamerGirlandCo Nov 26, 2025
de80fda
fix remaining tests
GamerGirlandCo Nov 26, 2025
482b231
update swagger definitions
GamerGirlandCo Nov 26, 2025
dce49c9
fix remaining tests
GamerGirlandCo Nov 26, 2025
8f364fd
fix repo api url
GamerGirlandCo Nov 26, 2025
d76108c
fix a couple more tests
GamerGirlandCo Nov 26, 2025
8f926f3
update swagger tool
GamerGirlandCo Nov 26, 2025
9b62e75
more test fixes
GamerGirlandCo Nov 26, 2025
908cb59
fix permissions on web issue routes
GamerGirlandCo Nov 26, 2025
4827259
fix org test
GamerGirlandCo Nov 26, 2025
125ed84
add group id to file comparison urls
GamerGirlandCo Nov 26, 2025
36f278e
fix more test urls
GamerGirlandCo Nov 26, 2025
2f825d4
move test repo 21 to different subgroup
GamerGirlandCo Nov 26, 2025
d1d4ae4
fix org repo test
GamerGirlandCo Nov 26, 2025
58e8e3f
revert changes to cases in `org_test.go`
GamerGirlandCo Nov 26, 2025
74c68db
add function to find teams a user is part of within a group
GamerGirlandCo Nov 30, 2025
c20d095
update `GetUserRepoPermission`
GamerGirlandCo Nov 30, 2025
c669de1
sync with main
GamerGirlandCo Nov 30, 2025
befb29f
fix group team unit query
GamerGirlandCo Dec 1, 2025
0ab713f
fix failing tests
GamerGirlandCo Dec 1, 2025
e0af9b2
update test fixtures
GamerGirlandCo Dec 1, 2025
f72490e
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
83f0f96
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
461ce57
update repository storage layout as per https://github.com/go-gitea/g…
GamerGirlandCo Aug 17, 2025
10fb828
fix broken hooks
GamerGirlandCo Aug 18, 2025
f0aa765
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
9a2f578
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
d00d896
begin work on base subfeatures
GamerGirlandCo Aug 13, 2025
bd52b39
ensure we do not display an add button when viewing a group's projects
GamerGirlandCo Aug 13, 2025
0b30f87
add template for creating a new group
GamerGirlandCo Aug 13, 2025
093cf09
add templates for group settings page
GamerGirlandCo Aug 13, 2025
9352cdf
add template for group selection dropdown
GamerGirlandCo Aug 13, 2025
84be051
add templates for main group page
GamerGirlandCo Aug 13, 2025
80bbb2a
create new types for the frontend
GamerGirlandCo Aug 13, 2025
2b953d3
create templates to display a sidebar containing a user's groups in a…
GamerGirlandCo Aug 13, 2025
3a3fbf2
add structs describing group-related forms
GamerGirlandCo Aug 13, 2025
e1cff12
add sidebar which displays accessible group hierarchy to organization…
GamerGirlandCo Aug 15, 2025
99d1e2d
add drag-and-drop functionality to org group sidebar
GamerGirlandCo Aug 15, 2025
984f0d0
add new styles
GamerGirlandCo Aug 15, 2025
ce1998c
add a menu for selecting parent group to repo creation page
GamerGirlandCo Aug 15, 2025
6857c5f
add `group_id` field to repo creation forms
GamerGirlandCo Aug 15, 2025
c4e2202
add templates for pages to add and manage teams with access to a group
GamerGirlandCo Aug 15, 2025
869e5a0
add `LoadHeaderCount` function for group pages
GamerGirlandCo Aug 15, 2025
6084aa0
make group selection in the new repository form look more hierarchical
GamerGirlandCo Aug 16, 2025
bd51cb1
update org home page to show group navigation menu on the right
GamerGirlandCo Aug 16, 2025
754a23c
add missing class to the group selector in the repo creation form
GamerGirlandCo Aug 16, 2025
ac1c78a
update group homepage template to reflect new file paths
GamerGirlandCo Aug 16, 2025
8b66a0c
remove `SafeHTML` calls in group team page template
GamerGirlandCo Aug 16, 2025
248ed6c
add missing imports to `index-domready.ts`
GamerGirlandCo Aug 16, 2025
42e3d3a
inject group-related values in `OrgAssignment`
GamerGirlandCo Aug 16, 2025
cd1393a
inject group-related values into web context
GamerGirlandCo Aug 16, 2025
8c8f814
add functions to populate web context with group info where appropriate
GamerGirlandCo Aug 16, 2025
644168b
add methods for retrieving nesting depth and generating a left paddin…
GamerGirlandCo Aug 16, 2025
709b95b
remove `Projects` tab from group header menu
GamerGirlandCo Aug 16, 2025
cb809bc
export `GetUnitPerms` from `routers/web/org` package for reuse in fut…
GamerGirlandCo Aug 16, 2025
b3ee8b6
add group pages to web router
GamerGirlandCo Aug 16, 2025
17e53a4
add component for searching for teams to add to a group
GamerGirlandCo Aug 16, 2025
55118a9
add ability to search for repository activity based on repo groups
GamerGirlandCo Aug 16, 2025
009b142
inject group id and organization name into dashboard repo list's data…
GamerGirlandCo Aug 16, 2025
c1324ba
create templates for group selection menu displayed in organization d…
GamerGirlandCo Aug 16, 2025
a008691
add group-scoped dashboard pages for issues, pull requests and milest…
GamerGirlandCo Aug 16, 2025
31efeb6
add `sortablejs-vue3` and `object-hash` dependencies
GamerGirlandCo Aug 16, 2025
20d56b9
create vue components to construct reorderable group hierarchy in das…
GamerGirlandCo Aug 16, 2025
3014d9f
modify DashboardRepoList component to show DashboardRepoGroup instead…
GamerGirlandCo Aug 16, 2025
323f8c3
fix js/ts linter errors
GamerGirlandCo Aug 16, 2025
dd33eac
run formatter and fix lint errors
GamerGirlandCo Aug 17, 2025
ca9ac98
fix another lint error
GamerGirlandCo Aug 17, 2025
f8c31e1
fix vet errors
GamerGirlandCo Aug 17, 2025
ce4b82d
add group breadcrumbs to repo page header
GamerGirlandCo Aug 18, 2025
8953613
fix some issue/pull URLs in javascript
GamerGirlandCo Aug 18, 2025
709fee0
ensure that only root-level repos are displayed on org homepage
GamerGirlandCo Aug 18, 2025
1eafe89
use group_service to move groups and repos after dragging and dropping
GamerGirlandCo Aug 18, 2025
109b2cb
fix `data-url` in root level group tree sortable
GamerGirlandCo Aug 18, 2025
d04432d
fix bug where group sort order is not updated correctly
GamerGirlandCo Aug 22, 2025
6b002db
remove references to `db.DefaultContext`
GamerGirlandCo Nov 22, 2025
124e280
update pnpm-lock.yaml
GamerGirlandCo Nov 22, 2025
4f7234e
remove references to `db.DefaultContext`
GamerGirlandCo Nov 23, 2025
e0d1144
tweak styles for dashboard group list
GamerGirlandCo Nov 23, 2025
b87cb78
display all repos as flat list if on homepage
GamerGirlandCo Nov 23, 2025
b573765
run formatter
GamerGirlandCo Nov 23, 2025
aa5719e
fix nil pointer dereference
GamerGirlandCo Nov 26, 2025
50e2cf3
run formatter and linter
GamerGirlandCo Nov 26, 2025
820861e
add copyright
GamerGirlandCo Nov 26, 2025
3aeb9d3
format templates
GamerGirlandCo Nov 26, 2025
fa2a2f2
update team repository template to use repository URL and FullName me…
GamerGirlandCo Nov 30, 2025
7a56248
update group web context
GamerGirlandCo Nov 30, 2025
75c8e02
update context assignment functions for repositories and repo groups
GamerGirlandCo Nov 30, 2025
02300ca
update group team routes
GamerGirlandCo Nov 30, 2025
f3ceb66
fix group assignment
GamerGirlandCo Dec 1, 2025
ba74fcd
tweak styles on page for editing teams in a group
GamerGirlandCo Dec 1, 2025
9567d2b
ensure group header only shows `teams` link if actor is group admin o…
GamerGirlandCo Dec 1, 2025
ab5a863
update common group assignment, add nil check when getting repo group…
GamerGirlandCo Dec 1, 2025
130bc9f
run formatter
GamerGirlandCo Dec 1, 2025
9aa6078
fix up repos inside groups being inaccessible in spite of actor being…
GamerGirlandCo Dec 2, 2025
fccbcb7
update an org test to add a team to a repo group
GamerGirlandCo Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ endif

SWAGGER_SPEC := templates/swagger/v1_json.tmpl
SWAGGER_SPEC_INPUT := templates/swagger/v1_input.json
SWAGGER_SPEC_GROUP_INPUT := templates/swagger/v1_groups.json
SWAGGER_EXCLUDE := code.gitea.io/sdk

TEST_MYSQL_HOST ?= mysql:3306
Expand Down Expand Up @@ -292,6 +293,8 @@ generate-swagger: $(SWAGGER_SPEC) ## generate the swagger spec from code comment

$(SWAGGER_SPEC): $(GO_SOURCES) $(SWAGGER_SPEC_INPUT)
$(GO) run $(SWAGGER_PACKAGE) generate spec --exclude "$(SWAGGER_EXCLUDE)" --input "$(SWAGGER_SPEC_INPUT)" --output './$(SWAGGER_SPEC)'
$(GO) generate -v ./build_tools/...
$(GO) run $(SWAGGER_PACKAGE) mixin -o './$(SWAGGER_SPEC)' $(SWAGGER_SPEC) $(SWAGGER_SPEC_GROUP_INPUT)

.PHONY: swagger-check
swagger-check: generate-swagger
Expand Down
306 changes: 306 additions & 0 deletions build_tools/swagger/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,306 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:generate go run main.go ../../

package main

import (
"bytes"
encjson "encoding/json" //nolint:depguard // this package wraps it
"errors"
"fmt"
"iter"
"log"
"os"
"path/filepath"
"regexp"

"code.gitea.io/gitea/modules/json"
)

type Pair struct {
Key string
Value any
}

type OrderedMap struct {
Pairs []Pair
indices map[string]int
}

func (o OrderedMap) Get(key string) (any, bool) {
if _, ok := o.indices[key]; ok {
return o.Pairs[o.indices[key]].Value, true
}
return nil, false
}

func (o *OrderedMap) Set(key string, value any) {
if _, ok := o.indices[key]; ok {
o.Pairs[o.indices[key]] = Pair{key, value}
} else {
o.Pairs = append(o.Pairs, Pair{key, value})
o.indices[key] = len(o.Pairs) - 1
}
}

func (o OrderedMap) Iter() iter.Seq2[string, any] {
return func(yield func(string, any) bool) {
for _, it := range o.Pairs {
yield(it.Key, it.Value)
}
}
}

func (o *OrderedMap) UnmarshalJSON(data []byte) error {
trimmed := bytes.TrimSpace(data)
if bytes.Equal(trimmed, []byte("null")) {
o.Pairs = nil
o.indices = nil
return nil
}

dec := encjson.NewDecoder(bytes.NewReader(data))
dec.UseNumber()

tok, err := dec.Token()
if err != nil {
return err
}
delim, ok := tok.(encjson.Delim)
if !ok || delim != '{' {
return errors.New("OrderedMap: expected '{' at start of object")
}

// Reset storage
if o.indices == nil {
o.indices = make(map[string]int)
} else {
for k := range o.indices {
delete(o.indices, k)
}
}
o.Pairs = o.Pairs[:0]

for dec.More() {
tk, err := dec.Token()
if err != nil {
return err
}
key, ok := tk.(string)
if !ok {
return fmt.Errorf(
"OrderedMap: expected string key, got %T (%v)",
tk,
tk,
)
}

var raw encjson.RawMessage
if err := dec.Decode(&raw); err != nil {
return fmt.Errorf("OrderedMap: decode value for %q: %w", key, err)
}

val, err := decodeJSONValue(raw)
if err != nil {
return fmt.Errorf("OrderedMap: unmarshal value for %q: %w", key, err)
}

if idx, exists := o.indices[key]; exists {
o.Pairs[idx].Value = val
} else {
o.indices[key] = len(o.Pairs)
o.Pairs = append(o.Pairs, Pair{Key: key, Value: val})
}
}

end, err := dec.Token()
if err != nil {
return err
}
if d, ok := end.(encjson.Delim); !ok || d != '}' {
return errors.New("OrderedMap: expected '}' at end of object")
}

return nil
}

func decodeJSONValue(raw encjson.RawMessage) (any, error) {
t := bytes.TrimSpace(raw)
if bytes.Equal(t, []byte("null")) {
return nil, nil
}

d := encjson.NewDecoder(bytes.NewReader(raw))
d.UseNumber()

tok, err := d.Token()
if err != nil {
return nil, err
}

switch tt := tok.(type) {
case encjson.Delim:
switch tt {
case '{':
var inner OrderedMap
if err := inner.UnmarshalJSON(raw); err != nil {
return nil, err
}
return inner, nil
case '[':
var arr []any
for d.More() {
var elemRaw encjson.RawMessage
if err := d.Decode(&elemRaw); err != nil {
return nil, err
}
v, err := decodeJSONValue(elemRaw)
if err != nil {
return nil, err
}
arr = append(arr, v)
}
if end, err := d.Token(); err != nil {
return nil, err
} else if end != encjson.Delim(']') {
return nil, errors.New("expected ']'")
}
return arr, nil
default:
return nil, fmt.Errorf("unexpected delimiter %q", tt)
}
default:
var v any
d = encjson.NewDecoder(bytes.NewReader(raw))
d.UseNumber()
if err := d.Decode(&v); err != nil {
return nil, err
}
return v, nil
}
}

func (o OrderedMap) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer

buf.WriteString("{")
for i, kv := range o.Pairs {
if i != 0 {
buf.WriteString(",")
}
key, err := json.Marshal(kv.Key)
if err != nil {
return nil, err
}
buf.Write(key)
buf.WriteString(":")
val, err := json.Marshal(kv.Value)
if err != nil {
return nil, err
}
buf.Write(val)
}

buf.WriteString("}")
return buf.Bytes(), nil
}

var rxPath = regexp.MustCompile(`(?m)^(/repos/\{owner})/(\{repo})`)

func generatePaths(root string) *OrderedMap {
pathData := &OrderedMap{
indices: make(map[string]int),
}
endpoints := &OrderedMap{
indices: make(map[string]int),
}
fileToRead, err := filepath.Rel(root, "./templates/swagger/v1_json.tmpl")
if err != nil {
log.Fatal(err)
}
swaggerBytes, err := os.ReadFile(fileToRead)
if err != nil {
log.Fatal(err)
}
raw := OrderedMap{
indices: make(map[string]int),
}
err = json.Unmarshal(swaggerBytes, &raw)
if err != nil {
log.Fatal(err)
}
rpaths, has := raw.Get("paths")
if !has {
log.Fatal("paths not found")
}
paths := rpaths.(OrderedMap)
for k, v := range paths.Iter() {
if !rxPath.MatchString(k) {
// skip if this endpoint does not start with `/repos/{owner}/{repo}`
continue
}
// generate new endpoint path with `/group/{group_id}` in between the `owner` and `repo` params
nk := rxPath.ReplaceAllString(k, "$1/group/{group_id}/$2")
methodMap := v.(OrderedMap)

for method, methodSpec := range methodMap.Iter() {
specMap := methodSpec.(OrderedMap)
var params []OrderedMap
aparams, has := specMap.Get("parameters")
if !has {
continue
}
rparams := aparams.([]any)
for _, rparam := range rparams {
params = append(params, rparam.(OrderedMap))
}
param := OrderedMap{
indices: make(map[string]int),
}
param.Set("description", "group ID of the repo")
param.Set("name", "group_id")
param.Set("type", "integer")
param.Set("format", "int64")
param.Set("required", true)
param.Set("in", "path")
params = append(params, param)
// i believe for...range loops create copies of each item that's iterated over,
// so we need to take extra care to ensure we're mutating the original map entry
specMap.Set("parameters", params)
methodMap.Set(method, specMap)
//(methodMap[method].(map[string]any))["parameters"] = params
}
endpoints.Set(nk, methodMap)
}
pathData.Set("paths", endpoints)
return pathData
}

func writeMapToFile(filename string, data *OrderedMap) {
bytes, err := json.MarshalIndent(data, "", " ")
if err != nil {
log.Fatal(err)
}
bytes = append(bytes, '\n')
err = os.WriteFile(filename, bytes, 0o666)
if err != nil {
log.Fatal(err)
}
}

func main() {
var err error
root := "../../"
if len(os.Args) > 1 {
root = os.Args[1]
}
err = os.Chdir(root)
if err != nil {
log.Fatal(err)
}

pathData := generatePaths(".")
out := "./templates/swagger/v1_groups.json"
writeMapToFile(out, pathData)
}
Loading