Repository: urfave/cli (go)

Issue:
Using comma in flag name for alternatives breaks
## my urfave/cli version is

_**v1.22.4**_

## Checklist

* [X] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases).
* [X] Did you check the manual for your release? The v1 manual is [here](https://github.com/urfave/cli/blob/master/docs/v1/manual.md)
* [X] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.

## Dependency Management

- My project is using go modules.
- My project is using vendoring.

## Describe the bug

When using alternates in flag names altsrc does not copy the flag value.

## To reproduce

```go
package main

import (
  "fmt"
  "log"
  "os"

  "github.com/urfave/cli"
  "github.com/urfave/cli/altsrc"
)

var (
  test int
)

func main() {
  app := cli.NewApp()

  flags := []cli.Flag{
    altsrc.NewIntFlag(cli.IntFlag{Name: "test,t", Destination: &test}),
    cli.StringFlag{Name: "load"},
  }

  app.Action = func(c *cli.Context) error {
    fmt.Printf("Have test value: %d\n", test)
    return nil
  }

  app.Before = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load"))
  app.Flags = flags

  err := app.Run(os.Args)
  if err != nil {
    log.Fatal(err)
  }
}
```
```sh
echo test: 1 >conf
GO111MODULE=on go run test.go --load conf
```
## Observed behavior

```
Have test value: 0
```

## Expected behavior

```
Have test value: 1
```

## Additional context

Previously reported in #711

Pull request description:
Fix:(issue_1142). Allow comma in altsrc flag names
<!--
  This template provides some ideas of things to include in your PR description.
  To start, try providing a short summary of your changes in the Title above.
  If a section of the PR template does not apply to this PR, then delete that section.
 -->

## What type of PR is this?

_(REQUIRED)_

<!--
  Delete any of the following that do not apply:
 -->

- bug

## What this PR does / why we need it:

_(REQUIRED)_

<!--
  What goal is this change working towards?
  Provide a bullet pointed summary of how each file was changed.
  Briefly explain any decisions you made with respect to the changes.
  Include anything here that you didn't include in *Release Notes*
  above, such as changes to CI or changes to internal methods.
-->

Allow altsrc flags to have comma in name

## Which issue(s) this PR fixes:

_(REQUIRED)_

<!--
If this PR fixes one of more issues, list them here.
One line each, like so:

Fixes #123
Fixes #39
-->

Fixes #1142 
## Special notes for your reviewer:

_(fill-in or delete this section)_

<!--
   Is there any particular feedback you would / wouldn't like?
   Which parts of the code should reviewers focus on?
-->

## Testing

_(fill-in or delete this section)_

<!--
  Describe how you tested this change.
-->

Updated altsrc tests

go test ./altsrc/...

## Release Notes

_(REQUIRED)_
<!--
  If this PR makes user facing changes, please describe them here. This
  description will be copied into the release notes/changelog, whenever the
  next version is released. Keep this section short, and focus on high level
  changes.

  Put your text between the block. To omit notes, use NONE within the block.
-->

```release-note

```


Patch:
diff --git a/altsrc/flag.go b/altsrc/flag.go
index afb4ad4..6fb275f 100644
--- a/altsrc/flag.go
+++ b/altsrc/flag.go
@@ -5,6 +5,7 @@ import (
 	"strconv"
 	"strings"
 	"syscall"
+	"time"
 
 	"github.com/urfave/cli"
 )
@@ -85,14 +86,17 @@ func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourc
 func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
-			value, err := isc.StringSlice(f.StringSliceFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value []string
+			eachName(f.StringSliceFlag.Name, func(name string) {
+				val, err := isc.StringSlice(name)
+				if err == nil && value == nil {
+					value = val
+				}
+			})
 			if value != nil {
 				var sliceValue cli.StringSlice = value
 				eachName(f.Name, func(name string) {
-					underlyingFlag := f.set.Lookup(f.Name)
+					underlyingFlag := f.set.Lookup(name)
 					if underlyingFlag != nil {
 						underlyingFlag.Value = &sliceValue
 					}
@@ -107,14 +111,17 @@ func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputS
 func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
-			value, err := isc.IntSlice(f.IntSliceFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value []int
+			eachName(f.IntSliceFlag.Name, func(name string) {
+				val, err := isc.IntSlice(name)
+				if err == nil && value == nil {
+					value = val
+				}
+			})
 			if value != nil {
 				var sliceValue cli.IntSlice = value
 				eachName(f.Name, func(name string) {
-					underlyingFlag := f.set.Lookup(f.Name)
+					underlyingFlag := f.set.Lookup(name)
 					if underlyingFlag != nil {
 						underlyingFlag.Value = &sliceValue
 					}
@@ -129,13 +136,16 @@ func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
 func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
-			value, err := isc.Bool(f.BoolFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value bool
+			eachName(f.BoolFlag.Name, func(name string) {
+				val, err := isc.Bool(name)
+				if err == nil && !value {
+					value = val
+				}
+			})
 			if value {
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, strconv.FormatBool(value))
+					_ = f.set.Set(name, strconv.FormatBool(value))
 				})
 			}
 		}
@@ -147,13 +157,16 @@ func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
 func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
-			value, err := isc.BoolT(f.BoolTFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value bool
+			eachName(f.BoolTFlag.Name, func(name string) {
+				val, err := isc.Bool(name)
+				if err == nil && !value {
+					value = val
+				}
+			})
 			if !value {
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, strconv.FormatBool(value))
+					_ = f.set.Set(name, strconv.FormatBool(value))
 				})
 			}
 		}
@@ -165,13 +178,16 @@ func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceC
 func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
-			value, err := isc.String(f.StringFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value string
+			eachName(f.StringFlag.Name, func(name string) {
+				val, err := isc.String(name)
+				if err == nil && value == "" {
+					value = val
+				}
+			})
 			if value != "" {
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, value)
+					_ = f.set.Set(name, value)
 				})
 			}
 		}
@@ -183,13 +199,16 @@ func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSource
 func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
-			value, err := isc.Int(f.IntFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value int
+			eachName(f.IntFlag.Name, func(name string) {
+				val, err := isc.Int(name)
+				if err == nil && value == 0 {
+					value = val
+				}
+			})
 			if value > 0 {
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, strconv.FormatInt(int64(value), 10))
+					_ = f.set.Set(name, strconv.FormatInt(int64(value), 10))
 				})
 			}
 		}
@@ -201,13 +220,16 @@ func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCon
 func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
-			value, err := isc.Duration(f.DurationFlag.Name)
-			if err != nil {
-				return err
-			}
+			var value time.Duration
+			eachName(f.DurationFlag.Name, func(name string) {
+				val, err := isc.Duration(name)
+				if err == nil && value == 0 {
+					value = val
+				}
+			})
 			if value > 0 {
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, value.String())
+					_ = f.set.Set(name, value.String())
 				})
 			}
 		}
@@ -219,14 +241,17 @@ func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
 func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
 	if f.set != nil {
 		if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
-			value, err := isc.Float64(f.Float64Flag.Name)
-			if err != nil {
-				return err
-			}
+			var value float64
+			eachName(f.Float64Flag.Name, func(name string) {
+				val, err := isc.Float64(name)
+				if err == nil && value == 0 {
+					value = val
+				}
+			})
 			if value > 0 {
 				floatStr := float64ToString(value)
 				eachName(f.Name, func(name string) {
-					_ = f.set.Set(f.Name, floatStr)
+					_ = f.set.Set(name, floatStr)
 				})
 			}
 		}


Test patch:
diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go
index 90a96d3..bd77898 100644
--- a/altsrc/flag_test.go
+++ b/altsrc/flag_test.go
@@ -57,11 +57,12 @@ func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestStringSliceApplyInputSourceValue(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewStringSliceFlag(cli.StringSliceFlag{Name: "test"}),
+		Flag:     NewStringSliceFlag(cli.StringSliceFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: []interface{}{"hello", "world"},
 	})
 	expect(t, c.StringSlice("test"), []string{"hello", "world"})
+	expect(t, c.StringSlice("t"), []string{"hello", "world"})
 }
 
 func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) {
@@ -87,11 +88,12 @@ func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestIntSliceApplyInputSourceValue(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewIntSliceFlag(cli.IntSliceFlag{Name: "test"}),
+		Flag:     NewIntSliceFlag(cli.IntSliceFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: []interface{}{1, 2},
 	})
 	expect(t, c.IntSlice("test"), []int{1, 2})
+	expect(t, c.IntSlice("t"), []int{1, 2})
 }
 
 func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) {
@@ -117,11 +119,12 @@ func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestBoolApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewBoolFlag(cli.BoolFlag{Name: "test"}),
+		Flag:     NewBoolFlag(cli.BoolFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: true,
 	})
 	expect(t, true, c.Bool("test"))
+	expect(t, true, c.Bool("t"))
 }
 
 func TestBoolApplyInputSourceMethodContextSet(t *testing.T) {
@@ -147,11 +150,12 @@ func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestBoolTApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewBoolTFlag(cli.BoolTFlag{Name: "test"}),
+		Flag:     NewBoolTFlag(cli.BoolTFlag{Name: "test, t"}),
 		FlagName: "test",
 		MapValue: false,
 	})
 	expect(t, false, c.BoolT("test"))
+	expect(t, false, c.BoolT("t"))
 }
 
 func TestBoolTApplyInputSourceMethodContextSet(t *testing.T) {
@@ -177,11 +181,12 @@ func TestBoolTApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestStringApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewStringFlag(cli.StringFlag{Name: "test"}),
+		Flag:     NewStringFlag(cli.StringFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: "hello",
 	})
 	expect(t, "hello", c.String("test"))
+	expect(t, "hello", c.String("t"))
 }
 
 func TestStringApplyInputSourceMethodContextSet(t *testing.T) {
@@ -207,11 +212,12 @@ func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestIntApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewIntFlag(cli.IntFlag{Name: "test"}),
+		Flag:     NewIntFlag(cli.IntFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: 15,
 	})
 	expect(t, 15, c.Int("test"))
+	expect(t, 15, c.Int("t"))
 }
 
 func TestIntApplyInputSourceMethodContextSet(t *testing.T) {
@@ -237,11 +243,12 @@ func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestDurationApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewDurationFlag(cli.DurationFlag{Name: "test"}),
+		Flag:     NewDurationFlag(cli.DurationFlag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: 30 * time.Second,
 	})
 	expect(t, 30*time.Second, c.Duration("test"))
+	expect(t, 30*time.Second, c.Duration("t"))
 }
 
 func TestDurationApplyInputSourceMethodContextSet(t *testing.T) {
@@ -267,11 +274,12 @@ func TestDurationApplyInputSourceMethodEnvVarSet(t *testing.T) {
 
 func TestFloat64ApplyInputSourceMethodSet(t *testing.T) {
 	c := runTest(t, testApplyInputSource{
-		Flag:     NewFloat64Flag(cli.Float64Flag{Name: "test"}),
+		Flag:     NewFloat64Flag(cli.Float64Flag{Name: "test,t"}),
 		FlagName: "test",
 		MapValue: 1.3,
 	})
 	expect(t, 1.3, c.Float64("test"))
+	expect(t, 1.3, c.Float64("t"))
 }
 
 func TestFloat64ApplyInputSourceMethodContextSet(t *testing.T) {