mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 21:16:26 +01:00 
			
		
		
		
	Follow improve code quality (#21465)
After some discussion, introduce a new slice `brokenArgs` to make `gitCmd.Run()` return errors if any dynamic argument is invalid. Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
		
							parent
							
								
									d98c5db58f
								
							
						
					
					
						commit
						677af6ac57
					
				@ -40,6 +40,7 @@ type Command struct {
 | 
			
		||||
	parentContext    context.Context
 | 
			
		||||
	desc             string
 | 
			
		||||
	globalArgsLength int
 | 
			
		||||
	brokenArgs       []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) String() string {
 | 
			
		||||
@ -50,6 +51,7 @@ func (c *Command) String() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCommand creates and returns a new Git Command based on given command and arguments.
 | 
			
		||||
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
 | 
			
		||||
func NewCommand(ctx context.Context, args ...string) *Command {
 | 
			
		||||
	// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it
 | 
			
		||||
	cargs := make([]string, len(globalCommandArgs))
 | 
			
		||||
@ -63,11 +65,13 @@ func NewCommand(ctx context.Context, args ...string) *Command {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
 | 
			
		||||
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
 | 
			
		||||
func NewCommandNoGlobals(args ...string) *Command {
 | 
			
		||||
	return NewCommandContextNoGlobals(DefaultContext, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCommandContextNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
 | 
			
		||||
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
 | 
			
		||||
func NewCommandContextNoGlobals(ctx context.Context, args ...string) *Command {
 | 
			
		||||
	return &Command{
 | 
			
		||||
		name:          GitExecutable,
 | 
			
		||||
@ -89,20 +93,24 @@ func (c *Command) SetDescription(desc string) *Command {
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddArguments adds new argument(s) to the command.
 | 
			
		||||
// AddArguments adds new argument(s) to the command. Each argument must be safe to be trusted.
 | 
			
		||||
// User-provided arguments should be passed to AddDynamicArguments instead.
 | 
			
		||||
func (c *Command) AddArguments(args ...string) *Command {
 | 
			
		||||
	c.args = append(c.args, args...)
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddDynamicArguments adds new dynamic argument(s) to the command.
 | 
			
		||||
// If the argument is invalid (it shouldn't happen in real life), it panics to caller
 | 
			
		||||
// The arguments may come from user input and can not be trusted, so no leading '-' is allowed to avoid passing options
 | 
			
		||||
func (c *Command) AddDynamicArguments(args ...string) *Command {
 | 
			
		||||
	for _, arg := range args {
 | 
			
		||||
		if arg != "" && arg[0] == '-' {
 | 
			
		||||
			panic("invalid argument: " + arg)
 | 
			
		||||
			c.brokenArgs = append(c.brokenArgs, arg)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(c.brokenArgs) != 0 {
 | 
			
		||||
		return c
 | 
			
		||||
	}
 | 
			
		||||
	c.args = append(c.args, args...)
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
@ -150,8 +158,14 @@ func CommonCmdServEnvs() []string {
 | 
			
		||||
	return commonBaseEnvs()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var ErrBrokenCommand = errors.New("git command is broken")
 | 
			
		||||
 | 
			
		||||
// Run runs the command with the RunOpts
 | 
			
		||||
func (c *Command) Run(opts *RunOpts) error {
 | 
			
		||||
	if len(c.brokenArgs) != 0 {
 | 
			
		||||
		log.Error("git command is broken: %s, broken args: %s", c.String(), strings.Join(c.brokenArgs, " "))
 | 
			
		||||
		return ErrBrokenCommand
 | 
			
		||||
	}
 | 
			
		||||
	if opts == nil {
 | 
			
		||||
		opts = &RunOpts{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -27,15 +27,13 @@ func TestRunWithContextStd(t *testing.T) {
 | 
			
		||||
		assert.Empty(t, stdout)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert.Panics(t, func() {
 | 
			
		||||
		cmd = NewCommand(context.Background())
 | 
			
		||||
		cmd.AddDynamicArguments("-test")
 | 
			
		||||
	})
 | 
			
		||||
	cmd = NewCommand(context.Background())
 | 
			
		||||
	cmd.AddDynamicArguments("-test")
 | 
			
		||||
	assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
 | 
			
		||||
 | 
			
		||||
	assert.Panics(t, func() {
 | 
			
		||||
		cmd = NewCommand(context.Background())
 | 
			
		||||
		cmd.AddDynamicArguments("--test")
 | 
			
		||||
	})
 | 
			
		||||
	cmd = NewCommand(context.Background())
 | 
			
		||||
	cmd.AddDynamicArguments("--test")
 | 
			
		||||
	assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
 | 
			
		||||
 | 
			
		||||
	subCmd := "version"
 | 
			
		||||
	cmd = NewCommand(context.Background()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user