@@ -7,20 +7,27 @@ import (
7
7
"context"
8
8
"errors"
9
9
"fmt"
10
+ "os"
11
+ "path/filepath"
12
+ "strings"
10
13
14
+ activities_model "code.gitea.io/gitea/models/activities"
11
15
"code.gitea.io/gitea/models/db"
12
16
"code.gitea.io/gitea/models/git"
13
17
issues_model "code.gitea.io/gitea/models/issues"
14
18
"code.gitea.io/gitea/models/organization"
19
+ access_model "code.gitea.io/gitea/models/perm/access"
15
20
repo_model "code.gitea.io/gitea/models/repo"
16
21
"code.gitea.io/gitea/models/unit"
17
22
user_model "code.gitea.io/gitea/models/user"
18
23
"code.gitea.io/gitea/modules/graceful"
24
+ issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
19
25
"code.gitea.io/gitea/modules/log"
20
26
"code.gitea.io/gitea/modules/queue"
21
27
repo_module "code.gitea.io/gitea/modules/repository"
22
28
"code.gitea.io/gitea/modules/setting"
23
29
"code.gitea.io/gitea/modules/structs"
30
+ "code.gitea.io/gitea/modules/util"
24
31
notify_service "code.gitea.io/gitea/services/notify"
25
32
pull_service "code.gitea.io/gitea/services/pull"
26
33
)
@@ -109,42 +116,32 @@ func Init(ctx context.Context) error {
109
116
110
117
// UpdateRepository updates a repository
111
118
func UpdateRepository (ctx context.Context , repo * repo_model.Repository , visibilityChanged bool ) (err error ) {
112
- ctx , committer , err := db .TxContext (ctx )
113
- if err != nil {
114
- return err
115
- }
116
- defer committer .Close ()
117
-
118
- if err = repo_module .UpdateRepository (ctx , repo , visibilityChanged ); err != nil {
119
- return fmt .Errorf ("updateRepository: %w" , err )
120
- }
121
-
122
- return committer .Commit ()
123
- }
124
-
125
- func UpdateRepositoryVisibility (ctx context.Context , repo * repo_model.Repository , isPrivate bool ) (err error ) {
126
- ctx , committer , err := db .TxContext (ctx )
127
- if err != nil {
128
- return err
129
- }
130
-
131
- defer committer .Close ()
132
-
133
- repo .IsPrivate = isPrivate
134
-
135
- if err = repo_module .UpdateRepository (ctx , repo , true ); err != nil {
136
- return fmt .Errorf ("UpdateRepositoryVisibility: %w" , err )
137
- }
138
-
139
- return committer .Commit ()
119
+ return db .WithTx (ctx , func (ctx context.Context ) error {
120
+ if err = updateRepository (ctx , repo , visibilityChanged ); err != nil {
121
+ return fmt .Errorf ("updateRepository: %w" , err )
122
+ }
123
+ return nil
124
+ })
140
125
}
141
126
142
127
func MakeRepoPublic (ctx context.Context , repo * repo_model.Repository ) (err error ) {
143
- return UpdateRepositoryVisibility (ctx , repo , false )
128
+ return db .WithTx (ctx , func (ctx context.Context ) error {
129
+ repo .IsPrivate = false
130
+ if err = updateRepository (ctx , repo , true ); err != nil {
131
+ return fmt .Errorf ("MakeRepoPublic: %w" , err )
132
+ }
133
+ return nil
134
+ })
144
135
}
145
136
146
137
func MakeRepoPrivate (ctx context.Context , repo * repo_model.Repository ) (err error ) {
147
- return UpdateRepositoryVisibility (ctx , repo , true )
138
+ return db .WithTx (ctx , func (ctx context.Context ) error {
139
+ repo .IsPrivate = true
140
+ if err = updateRepository (ctx , repo , true ); err != nil {
141
+ return fmt .Errorf ("MakeRepoPrivate: %w" , err )
142
+ }
143
+ return nil
144
+ })
148
145
}
149
146
150
147
// LinkedRepository returns the linked repo if any
@@ -170,3 +167,97 @@ func LinkedRepository(ctx context.Context, a *repo_model.Attachment) (*repo_mode
170
167
}
171
168
return nil , - 1 , nil
172
169
}
170
+
171
+ // checkDaemonExportOK creates/removes git-daemon-export-ok for git-daemon...
172
+ func checkDaemonExportOK (ctx context.Context , repo * repo_model.Repository ) error {
173
+ if err := repo .LoadOwner (ctx ); err != nil {
174
+ return err
175
+ }
176
+
177
+ // Create/Remove git-daemon-export-ok for git-daemon...
178
+ daemonExportFile := filepath .Join (repo .RepoPath (), `git-daemon-export-ok` )
179
+
180
+ isExist , err := util .IsExist (daemonExportFile )
181
+ if err != nil {
182
+ log .Error ("Unable to check if %s exists. Error: %v" , daemonExportFile , err )
183
+ return err
184
+ }
185
+
186
+ isPublic := ! repo .IsPrivate && repo .Owner .Visibility == structs .VisibleTypePublic
187
+ if ! isPublic && isExist {
188
+ if err = util .Remove (daemonExportFile ); err != nil {
189
+ log .Error ("Failed to remove %s: %v" , daemonExportFile , err )
190
+ }
191
+ } else if isPublic && ! isExist {
192
+ if f , err := os .Create (daemonExportFile ); err != nil {
193
+ log .Error ("Failed to create %s: %v" , daemonExportFile , err )
194
+ } else {
195
+ f .Close ()
196
+ }
197
+ }
198
+
199
+ return nil
200
+ }
201
+
202
+ // updateRepository updates a repository with db context
203
+ func updateRepository (ctx context.Context , repo * repo_model.Repository , visibilityChanged bool ) (err error ) {
204
+ repo .LowerName = strings .ToLower (repo .Name )
205
+
206
+ e := db .GetEngine (ctx )
207
+
208
+ if _ , err = e .ID (repo .ID ).AllCols ().Update (repo ); err != nil {
209
+ return fmt .Errorf ("update: %w" , err )
210
+ }
211
+
212
+ if err = repo_module .UpdateRepoSize (ctx , repo ); err != nil {
213
+ log .Error ("Failed to update size for repository: %v" , err )
214
+ }
215
+
216
+ if visibilityChanged {
217
+ if err = repo .LoadOwner (ctx ); err != nil {
218
+ return fmt .Errorf ("LoadOwner: %w" , err )
219
+ }
220
+ if repo .Owner .IsOrganization () {
221
+ // Organization repository need to recalculate access table when visibility is changed.
222
+ if err = access_model .RecalculateTeamAccesses (ctx , repo , 0 ); err != nil {
223
+ return fmt .Errorf ("recalculateTeamAccesses: %w" , err )
224
+ }
225
+ }
226
+
227
+ // If repo has become private, we need to set its actions to private.
228
+ if repo .IsPrivate {
229
+ _ , err = e .Where ("repo_id = ?" , repo .ID ).Cols ("is_private" ).Update (& activities_model.Action {
230
+ IsPrivate : true ,
231
+ })
232
+ if err != nil {
233
+ return err
234
+ }
235
+
236
+ if err = repo_model .ClearRepoStars (ctx , repo .ID ); err != nil {
237
+ return err
238
+ }
239
+ }
240
+
241
+ // Create/Remove git-daemon-export-ok for git-daemon...
242
+ if err := checkDaemonExportOK (ctx , repo ); err != nil {
243
+ return err
244
+ }
245
+
246
+ forkRepos , err := repo_model .GetRepositoriesByForkID (ctx , repo .ID )
247
+ if err != nil {
248
+ return fmt .Errorf ("getRepositoriesByForkID: %w" , err )
249
+ }
250
+ for i := range forkRepos {
251
+ forkRepos [i ].IsPrivate = repo .IsPrivate || repo .Owner .Visibility == structs .VisibleTypePrivate
252
+ if err = updateRepository (ctx , forkRepos [i ], true ); err != nil {
253
+ return fmt .Errorf ("updateRepository[%d]: %w" , forkRepos [i ].ID , err )
254
+ }
255
+ }
256
+
257
+ // If visibility is changed, we need to update the issue indexer.
258
+ // Since the data in the issue indexer have field to indicate if the repo is public or not.
259
+ issue_indexer .UpdateRepoIndexer (ctx , repo .ID )
260
+ }
261
+
262
+ return nil
263
+ }
0 commit comments