mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-11-04 03:05:26 +01:00 
			
		
		
		
	feat: add validation for object-format flag in repo create command (#741)
This PR adds validation for the `--object-format` flag in the `repo create` command. The flag now accepts only `sha1` or `sha256` as valid values, and returns an error for any other value. Changes: - Added validation in `runRepoCreate` to check for valid object format values - Added unit tests to verify the validation logic - Fixed the field name from `ObjectFormat` to `ObjectFormatName` to match the SDK The changes ensure that users get clear error messages when using invalid object format values, improving the user experience. Fix #727 Fix #660 Fix #767 Co-authored-by: techknowlogick <techknowlogick@noreply.gitea.com> Reviewed-on: https://gitea.com/gitea/tea/pulls/741 Reviewed-by: TheFox0x7 <thefox0x7@noreply.gitea.com>
This commit is contained in:
		@@ -4,8 +4,21 @@ on:
 | 
				
			|||||||
  - pull_request
 | 
					  - pull_request
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jobs:
 | 
					jobs:
 | 
				
			||||||
 | 
					  govulncheck_job:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    name: Run govulncheck
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - id: govulncheck
 | 
				
			||||||
 | 
					        uses: golang/govulncheck-action@v1
 | 
				
			||||||
 | 
					        with:
 | 
				
			||||||
 | 
					          go-version-file: 'go.mod'
 | 
				
			||||||
  check-and-test:
 | 
					  check-and-test:
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    env:
 | 
				
			||||||
 | 
					      HTTP_PROXY: ""
 | 
				
			||||||
 | 
					      GITEA_TEA_TEST_URL: "http://gitea:3000"
 | 
				
			||||||
 | 
					      GITEA_TEA_TEST_USERNAME: "test01"
 | 
				
			||||||
 | 
					      GITEA_TEA_TEST_PASSWORD: "test01"
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - uses: actions/checkout@v4
 | 
					      - uses: actions/checkout@v4
 | 
				
			||||||
      - uses: actions/setup-go@v5
 | 
					      - uses: actions/setup-go@v5
 | 
				
			||||||
@@ -20,7 +33,32 @@ jobs:
 | 
				
			|||||||
          make misspell-check
 | 
					          make misspell-check
 | 
				
			||||||
          make docs-check
 | 
					          make docs-check
 | 
				
			||||||
          make build
 | 
					          make build
 | 
				
			||||||
 | 
					      - run: curl --noproxy "*" http://gitea:3000/api/v1/version # verify connection to instance
 | 
				
			||||||
      - name: test and coverage
 | 
					      - name: test and coverage
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          make test
 | 
					          make test
 | 
				
			||||||
          make unit-test-coverage
 | 
					          make unit-test-coverage
 | 
				
			||||||
 | 
					    services:
 | 
				
			||||||
 | 
					      gitea:
 | 
				
			||||||
 | 
					        image: docker.gitea.com/gitea:1.24.5
 | 
				
			||||||
 | 
					        cmd:
 | 
				
			||||||
 | 
					          - bash
 | 
				
			||||||
 | 
					          - -c
 | 
				
			||||||
 | 
					          - >-
 | 
				
			||||||
 | 
					            mkdir -p /tmp/conf/
 | 
				
			||||||
 | 
					            && mkdir -p /tmp/data/
 | 
				
			||||||
 | 
					            && echo "I_AM_BEING_UNSAFE_RUNNING_AS_ROOT = true" > /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "[security]" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1NTg4MzY4ODB9.LoKQyK5TN_0kMJFVHWUW0uDAyoGjDP6Mkup4ps2VJN4" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "INSTALL_LOCK   = true" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "SECRET_KEY     = 2crAW4UANgvLipDS6U5obRcFosjSJHQANll6MNfX7P0G3se3fKcCwwK3szPyGcbo" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "PASSWORD_COMPLEXITY = off" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "[database]" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "DB_TYPE = sqlite3" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "[repository]" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "ROOT = /tmp/data/" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "[server]" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && echo "ROOT_URL = http://gitea:3000" >> /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && gitea migrate -c /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && gitea admin user create --username=test01 --password=test01 --email=test01@gitea.io --admin=true --must-change-password=false --access-token -c /tmp/conf/app.ini
 | 
				
			||||||
 | 
					            && gitea web -c /tmp/conf/app.ini
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,6 +88,17 @@ var CmdRepoCreate = cli.Command{
 | 
				
			|||||||
			Name:  "trustmodel",
 | 
								Name:  "trustmodel",
 | 
				
			||||||
			Usage: "select trust model (committer,collaborator,collaborator+committer)",
 | 
								Usage: "select trust model (committer,collaborator,collaborator+committer)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:     "object-format",
 | 
				
			||||||
 | 
								Required: false,
 | 
				
			||||||
 | 
								Usage:    "select git object format (sha1,sha256)",
 | 
				
			||||||
 | 
								Validator: func(v string) error {
 | 
				
			||||||
 | 
									if v != "sha1" && v != "sha256" {
 | 
				
			||||||
 | 
										return fmt.Errorf("invalid object format '%s', must be either 'sha1' or 'sha256'", v)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}, flags.LoginOutputFlags...),
 | 
						}, flags.LoginOutputFlags...),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -125,6 +136,7 @@ func runRepoCreate(_ stdctx.Context, cmd *cli.Command) error {
 | 
				
			|||||||
		DefaultBranch:    ctx.String("branch"),
 | 
							DefaultBranch:    ctx.String("branch"),
 | 
				
			||||||
		Template:         ctx.Bool("template"),
 | 
							Template:         ctx.Bool("template"),
 | 
				
			||||||
		TrustModel:       trustmodel,
 | 
							TrustModel:       trustmodel,
 | 
				
			||||||
 | 
							ObjectFormatName: ctx.String("object-format"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(ctx.String("owner")) != 0 {
 | 
						if len(ctx.String("owner")) != 0 {
 | 
				
			||||||
		repo, _, err = client.CreateOrgRepo(ctx.String("owner"), opts)
 | 
							repo, _, err = client.CreateOrgRepo(ctx.String("owner"), opts)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										88
									
								
								cmd/repos/create_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								cmd/repos/create_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					// Copyright 2025 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package repos
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/sdk/gitea"
 | 
				
			||||||
 | 
						"code.gitea.io/tea/modules/task"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/urfave/cli/v3"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestCreateRepoObjectFormat(t *testing.T) {
 | 
				
			||||||
 | 
						giteaURL := os.Getenv("GITEA_TEA_TEST_URL")
 | 
				
			||||||
 | 
						if giteaURL == "" {
 | 
				
			||||||
 | 
							t.Skip("GITEA_TEA_TEST_URL is not set, skipping test")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						timestamp := time.Now().Unix()
 | 
				
			||||||
 | 
						tests := []struct {
 | 
				
			||||||
 | 
							name        string
 | 
				
			||||||
 | 
							args        []string
 | 
				
			||||||
 | 
							wantOpts    gitea.CreateRepoOption
 | 
				
			||||||
 | 
							wantErr     bool
 | 
				
			||||||
 | 
							errContains string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "create repo with sha1 object format",
 | 
				
			||||||
 | 
								args: []string{"--name", fmt.Sprintf("test-sha1-%d", timestamp), "--object-format", "sha1"},
 | 
				
			||||||
 | 
								wantOpts: gitea.CreateRepoOption{
 | 
				
			||||||
 | 
									Name:             fmt.Sprintf("test-sha1-%d", timestamp),
 | 
				
			||||||
 | 
									ObjectFormatName: "sha1",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name: "create repo with sha256 object format",
 | 
				
			||||||
 | 
								args: []string{"--name", fmt.Sprintf("test-sha256-%d", timestamp), "--object-format", "sha256"},
 | 
				
			||||||
 | 
								wantOpts: gitea.CreateRepoOption{
 | 
				
			||||||
 | 
									Name:             fmt.Sprintf("test-sha256-%d", timestamp),
 | 
				
			||||||
 | 
									ObjectFormatName: "sha256",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								wantErr: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name:        "create repo with invalid object format",
 | 
				
			||||||
 | 
								args:        []string{"--name", fmt.Sprintf("test-invalid-%d", timestamp), "--object-format", "invalid"},
 | 
				
			||||||
 | 
								wantErr:     true,
 | 
				
			||||||
 | 
								errContains: "invalid object format",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						giteaUserName := os.Getenv("GITEA_TEA_TEST_USERNAME")
 | 
				
			||||||
 | 
						giteaUserPasword := os.Getenv("GITEA_TEA_TEST_PASSWORD")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err := task.CreateLogin("test", "", giteaUserName, giteaUserPasword, "", "", "", giteaURL, "", "", true, false, false, false)
 | 
				
			||||||
 | 
						if err != nil && err.Error() != "login name 'test' has already been used" {
 | 
				
			||||||
 | 
							t.Fatal(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, tt := range tests {
 | 
				
			||||||
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								reposCmd := &cli.Command{
 | 
				
			||||||
 | 
									Name:     "repos",
 | 
				
			||||||
 | 
									Commands: []*cli.Command{&CmdRepoCreate},
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								tt.args = append(tt.args, "--login", "test")
 | 
				
			||||||
 | 
								args := append([]string{"repos", "create"}, tt.args...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								err := reposCmd.Run(context.Background(), args)
 | 
				
			||||||
 | 
								if tt.wantErr {
 | 
				
			||||||
 | 
									assert.Error(t, err)
 | 
				
			||||||
 | 
									if tt.errContains != "" {
 | 
				
			||||||
 | 
										assert.Contains(t, err.Error(), tt.errContains)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								assert.NoError(t, err)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1071,6 +1071,8 @@ Create a repository
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
**--name, -**="": name of new repo
 | 
					**--name, -**="": name of new repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**--object-format**="": select git object format (sha1,sha256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
 | 
					**--output, -o**="": Output format. (simple, table, csv, tsv, yaml, json)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**--owner, -O**="": name of repo owner
 | 
					**--owner, -O**="": name of repo owner
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -167,9 +167,13 @@ func generateToken(login config.Login, user, pass, otp, scopes string) (string,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var tokenScopes []gitea.AccessTokenScope
 | 
						var tokenScopes []gitea.AccessTokenScope
 | 
				
			||||||
 | 
						if len(scopes) == 0 {
 | 
				
			||||||
 | 
							tokenScopes = []gitea.AccessTokenScope{gitea.AccessTokenScopeAll}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
		for _, scope := range strings.Split(scopes, ",") {
 | 
							for _, scope := range strings.Split(scopes, ",") {
 | 
				
			||||||
			tokenScopes = append(tokenScopes, gitea.AccessTokenScope(strings.TrimSpace(scope)))
 | 
								tokenScopes = append(tokenScopes, gitea.AccessTokenScope(strings.TrimSpace(scope)))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t, _, err := client.CreateAccessToken(gitea.CreateAccessTokenOption{
 | 
						t, _, err := client.CreateAccessToken(gitea.CreateAccessTokenOption{
 | 
				
			||||||
		Name:   tokenName,
 | 
							Name:   tokenName,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user