github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/internal/tmpl/tmpl_test.go (about) 1 package tmpl 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 "text/template" 8 9 "github.com/goreleaser/goreleaser/internal/artifact" 10 "github.com/goreleaser/goreleaser/pkg/config" 11 "github.com/goreleaser/goreleaser/pkg/context" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestWithArtifact(t *testing.T) { 16 t.Parallel() 17 ctx := context.New(config.Project{ 18 ProjectName: "proj", 19 }) 20 ctx.ModulePath = "github.com/goreleaser/goreleaser" 21 ctx.Env = map[string]string{ 22 "FOO": "bar", 23 } 24 ctx.Version = "1.2.3" 25 ctx.Git.CurrentTag = "v1.2.3" 26 ctx.Semver = context.Semver{ 27 Major: 1, 28 Minor: 2, 29 Patch: 3, 30 } 31 ctx.Git.Branch = "test-branch" 32 ctx.Git.Commit = "commit" 33 ctx.Git.FullCommit = "fullcommit" 34 ctx.Git.ShortCommit = "shortcommit" 35 for expect, tmpl := range map[string]string{ 36 "bar": "{{.Env.FOO}}", 37 "Linux": "{{.Os}}", 38 "amd64": "{{.Arch}}", 39 "6": "{{.Arm}}", 40 "softfloat": "{{.Mips}}", 41 "1.2.3": "{{.Version}}", 42 "v1.2.3": "{{.Tag}}", 43 "1-2-3": "{{.Major}}-{{.Minor}}-{{.Patch}}", 44 "test-branch": "{{.Branch}}", 45 "commit": "{{.Commit}}", 46 "fullcommit": "{{.FullCommit}}", 47 "shortcommit": "{{.ShortCommit}}", 48 "binary": "{{.Binary}}", 49 "proj": "{{.ProjectName}}", 50 "github.com/goreleaser/goreleaser": "{{ .ModulePath }}", 51 "v2.0.0": "{{.Tag | incmajor }}", 52 "2.0.0": "{{.Version | incmajor }}", 53 "v1.3.0": "{{.Tag | incminor }}", 54 "1.3.0": "{{.Version | incminor }}", 55 "v1.2.4": "{{.Tag | incpatch }}", 56 "1.2.4": "{{.Version | incpatch }}", 57 } { 58 tmpl := tmpl 59 expect := expect 60 t.Run(expect, func(t *testing.T) { 61 t.Parallel() 62 result, err := New(ctx).WithArtifact( 63 &artifact.Artifact{ 64 Name: "not-this-binary", 65 Goarch: "amd64", 66 Goos: "linux", 67 Goarm: "6", 68 Gomips: "softfloat", 69 Extra: map[string]interface{}{ 70 "Binary": "binary", 71 }, 72 }, 73 map[string]string{"linux": "Linux"}, 74 ).Apply(tmpl) 75 require.NoError(t, err) 76 require.Equal(t, expect, result) 77 }) 78 } 79 80 t.Run("artifact without binary name", func(t *testing.T) { 81 t.Parallel() 82 result, err := New(ctx).WithArtifact( 83 &artifact.Artifact{ 84 Name: "another-binary", 85 Goarch: "amd64", 86 Goos: "linux", 87 Goarm: "6", 88 }, map[string]string{}, 89 ).Apply("{{ .Binary }}") 90 require.NoError(t, err) 91 require.Equal(t, ctx.Config.ProjectName, result) 92 }) 93 94 t.Run("template using artifact Fields with no artifact", func(t *testing.T) { 95 t.Parallel() 96 result, err := New(ctx).Apply("{{ .Os }}") 97 require.EqualError(t, err, `template: tmpl:1:3: executing "tmpl" at <.Os>: map has no entry for key "Os"`) 98 require.Empty(t, result) 99 }) 100 } 101 102 func TestEnv(t *testing.T) { 103 testCases := []struct { 104 desc string 105 in string 106 out string 107 }{ 108 { 109 desc: "with env", 110 in: "{{ .Env.FOO }}", 111 out: "BAR", 112 }, 113 { 114 desc: "with env", 115 in: "{{ .Env.BAR }}", 116 out: "", 117 }, 118 } 119 ctx := context.New(config.Project{}) 120 ctx.Env = map[string]string{ 121 "FOO": "BAR", 122 } 123 ctx.Git.CurrentTag = "v1.2.3" 124 for _, tC := range testCases { 125 t.Run(tC.desc, func(t *testing.T) { 126 out, _ := New(ctx).Apply(tC.in) 127 require.Equal(t, tC.out, out) 128 }) 129 } 130 } 131 132 func TestWithEnv(t *testing.T) { 133 ctx := context.New(config.Project{}) 134 ctx.Env = map[string]string{ 135 "FOO": "BAR", 136 } 137 ctx.Git.CurrentTag = "v1.2.3" 138 out, err := New(ctx).WithEnvS([]string{ 139 "FOO=foo", 140 "BAR=bar", 141 }).Apply("{{ .Env.FOO }}-{{ .Env.BAR }}") 142 require.NoError(t, err) 143 require.Equal(t, "foo-bar", out) 144 } 145 146 func TestFuncMap(t *testing.T) { 147 ctx := context.New(config.Project{ 148 ProjectName: "proj", 149 Env: []string{ 150 "FOO=bar", 151 }, 152 }) 153 wd, err := os.Getwd() 154 require.NoError(t, err) 155 156 ctx.Git.CurrentTag = "v1.2.4" 157 for _, tc := range []struct { 158 Template string 159 Name string 160 Expected string 161 }{ 162 { 163 Template: `{{ replace "v1.24" "v" "" }}`, 164 Name: "replace", 165 Expected: "1.24", 166 }, 167 { 168 Template: `{{ if index .Env "SOME_ENV" }}{{ .Env.SOME_ENV }}{{ else }}default value{{ end }}`, 169 Name: "default value", 170 Expected: "default value", 171 }, 172 { 173 Template: `{{ if index .Env "FOO" }}{{ .Env.FOO }}{{ else }}default value{{ end }}`, 174 Name: "default value set", 175 Expected: "bar", 176 }, 177 { 178 Template: `{{ time "2006-01-02" }}`, 179 Name: "time YYYY-MM-DD", 180 }, 181 { 182 Template: `{{ time "01/02/2006" }}`, 183 Name: "time MM/DD/YYYY", 184 }, 185 { 186 Template: `{{ time "01/02/2006" }}`, 187 Name: "time MM/DD/YYYY", 188 }, 189 { 190 Template: `{{ tolower "TEST" }}`, 191 Name: "tolower", 192 Expected: "test", 193 }, 194 { 195 Template: `{{ trimprefix "v1.2.4" "v" }}`, 196 Name: "trimprefix", 197 Expected: "1.2.4", 198 }, 199 { 200 Template: `{{ toupper "test" }}`, 201 Name: "toupper", 202 Expected: "TEST", 203 }, 204 { 205 Template: `{{ trim " test " }}`, 206 Name: "trim", 207 Expected: "test", 208 }, 209 { 210 Template: `{{ abs "file" }}`, 211 Name: "abs", 212 Expected: filepath.Join(wd, "file"), 213 }, 214 } { 215 out, err := New(ctx).Apply(tc.Template) 216 require.NoError(t, err) 217 if tc.Expected != "" { 218 require.Equal(t, tc.Expected, out) 219 } else { 220 require.NotEmpty(t, out) 221 } 222 } 223 } 224 225 func TestApplySingleEnvOnly(t *testing.T) { 226 ctx := context.New(config.Project{ 227 Env: []string{ 228 "FOO=value", 229 "BAR=another", 230 }, 231 }) 232 233 testCases := []struct { 234 name string 235 tpl string 236 expectedErr error 237 }{ 238 { 239 "empty tpl", 240 "", 241 nil, 242 }, 243 { 244 "whitespaces", 245 " ", 246 nil, 247 }, 248 { 249 "plain-text only", 250 "raw-token", 251 ExpectedSingleEnvErr{}, 252 }, 253 { 254 "variable with spaces", 255 "{{ .Env.FOO }}", 256 nil, 257 }, 258 { 259 "variable without spaces", 260 "{{.Env.FOO}}", 261 nil, 262 }, 263 { 264 "variable with outer spaces", 265 " {{ .Env.FOO }} ", 266 nil, 267 }, 268 { 269 "unknown variable", 270 "{{ .Env.UNKNOWN }}", 271 template.ExecError{}, 272 }, 273 { 274 "other interpolation", 275 "{{ .ProjectName }}", 276 ExpectedSingleEnvErr{}, 277 }, 278 } 279 for _, tc := range testCases { 280 t.Run(tc.name, func(t *testing.T) { 281 _, err := New(ctx).ApplySingleEnvOnly(tc.tpl) 282 if tc.expectedErr != nil { 283 require.Error(t, err) 284 } else { 285 require.NoError(t, err) 286 } 287 }) 288 } 289 } 290 291 func TestInvalidTemplate(t *testing.T) { 292 ctx := context.New(config.Project{}) 293 ctx.Git.CurrentTag = "v1.1.1" 294 _, err := New(ctx).Apply("{{{.Foo}") 295 require.EqualError(t, err, "template: tmpl:1: unexpected \"{\" in command") 296 } 297 298 func TestEnvNotFound(t *testing.T) { 299 ctx := context.New(config.Project{}) 300 ctx.Git.CurrentTag = "v1.2.4" 301 result, err := New(ctx).Apply("{{.Env.FOO}}") 302 require.Empty(t, result) 303 require.EqualError(t, err, `template: tmpl:1:6: executing "tmpl" at <.Env.FOO>: map has no entry for key "FOO"`) 304 } 305 306 func TestWithExtraFields(t *testing.T) { 307 ctx := context.New(config.Project{}) 308 out, _ := New(ctx).WithExtraFields(Fields{ 309 "MyCustomField": "foo", 310 }).Apply("{{ .MyCustomField }}") 311 require.Equal(t, "foo", out) 312 }