github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/snapcraft/snapcraft_test.go (about)

     1  package snapcraft
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/goreleaser/goreleaser/internal/artifact"
    10  	"github.com/goreleaser/goreleaser/internal/gio"
    11  	"github.com/goreleaser/goreleaser/internal/pipe"
    12  	"github.com/goreleaser/goreleaser/internal/skips"
    13  	"github.com/goreleaser/goreleaser/internal/testctx"
    14  	"github.com/goreleaser/goreleaser/internal/testlib"
    15  	"github.com/goreleaser/goreleaser/internal/yaml"
    16  	"github.com/goreleaser/goreleaser/pkg/config"
    17  	"github.com/goreleaser/goreleaser/pkg/context"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestContinueOnError(t *testing.T) {
    22  	require.True(t, Pipe{}.ContinueOnError())
    23  }
    24  
    25  func TestDescription(t *testing.T) {
    26  	require.NotEmpty(t, Pipe{}.String())
    27  }
    28  
    29  func TestRunPipeMissingInfo(t *testing.T) {
    30  	for eerr, snap := range map[error]config.Snapcraft{
    31  		ErrNoSummary: {
    32  			Description: "dummy desc",
    33  		},
    34  		ErrNoDescription: {
    35  			Summary: "dummy summary",
    36  		},
    37  		pipe.Skip("no summary nor description were provided"): {},
    38  	} {
    39  		t.Run(fmt.Sprintf("testing if %v happens", eerr), func(t *testing.T) {
    40  			ctx := testctx.NewWithCfg(config.Project{
    41  				Snapcrafts: []config.Snapcraft{
    42  					snap,
    43  				},
    44  			})
    45  			require.Equal(t, eerr, Pipe{}.Run(ctx))
    46  		})
    47  	}
    48  }
    49  
    50  func TestRunPipe(t *testing.T) {
    51  	testlib.CheckPath(t, "snapcraft")
    52  	folder := t.TempDir()
    53  	dist := filepath.Join(folder, "dist")
    54  	require.NoError(t, os.Mkdir(dist, 0o755))
    55  	ctx := testctx.NewWithCfg(config.Project{
    56  		ProjectName: "mybin",
    57  		Dist:        dist,
    58  		Snapcrafts: []config.Snapcraft{
    59  			{
    60  				NameTemplate:     "foo_{{.Arch}}",
    61  				Summary:          "test summary {{.ProjectName}}",
    62  				Description:      "test description {{.ProjectName}}",
    63  				Publish:          true,
    64  				Builds:           []string{"foo"},
    65  				ChannelTemplates: []string{"stable"},
    66  			},
    67  			{
    68  				NameTemplate:     "foo_and_bar_{{.Arch}}",
    69  				Summary:          "test summary",
    70  				Description:      "test description",
    71  				Publish:          true,
    72  				Builds:           []string{"foo", "bar"},
    73  				ChannelTemplates: []string{"stable"},
    74  			},
    75  			{
    76  				NameTemplate:     "bar_{{.Arch}}",
    77  				Summary:          "test summary",
    78  				Description:      "test description",
    79  				Publish:          true,
    80  				Builds:           []string{"bar"},
    81  				ChannelTemplates: []string{"stable"},
    82  			},
    83  			{
    84  				NameTemplate:     "bar_{{.Arch}}",
    85  				Summary:          "test summary",
    86  				Description:      "test description",
    87  				Publish:          true,
    88  				Builds:           []string{"bar"},
    89  				ChannelTemplates: []string{"stable"},
    90  				Disable:          "{{.Env.SKIP}}",
    91  			},
    92  		},
    93  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"), testctx.WithEnv(map[string]string{"SKIP": "true"}))
    94  	addBinaries(t, ctx, "foo", filepath.Join(dist, "foo"))
    95  	addBinaries(t, ctx, "bar", filepath.Join(dist, "bar"))
    96  	testlib.AssertSkipped(t, Pipe{}.Run(ctx))
    97  	list := ctx.Artifacts.Filter(artifact.ByType(artifact.PublishableSnapcraft)).List()
    98  	require.Len(t, list, 9)
    99  }
   100  
   101  func TestBadTemolate(t *testing.T) {
   102  	testlib.CheckPath(t, "snapcraft")
   103  	folder := t.TempDir()
   104  	dist := filepath.Join(folder, "dist")
   105  	require.NoError(t, os.Mkdir(dist, 0o755))
   106  	ctx := testctx.NewWithCfg(config.Project{
   107  		ProjectName: "mybin",
   108  		Dist:        dist,
   109  		Snapcrafts: []config.Snapcraft{
   110  			{
   111  				NameTemplate:     "foo_{{.Arch}}",
   112  				Publish:          true,
   113  				Builds:           []string{"foo"},
   114  				ChannelTemplates: []string{"stable"},
   115  			},
   116  		},
   117  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   118  	addBinaries(t, ctx, "foo", filepath.Join(dist, "foo"))
   119  
   120  	t.Run("description", func(t *testing.T) {
   121  		ctx.Config.Snapcrafts[0].Description = "{{.Bad}}"
   122  		ctx.Config.Snapcrafts[0].Summary = "summary"
   123  		require.Error(t, Pipe{}.Run(ctx))
   124  	})
   125  
   126  	t.Run("summary", func(t *testing.T) {
   127  		ctx.Config.Snapcrafts[0].Description = "description"
   128  		ctx.Config.Snapcrafts[0].Summary = "{{.Bad}}"
   129  		require.Error(t, Pipe{}.Run(ctx))
   130  	})
   131  }
   132  
   133  func TestRunPipeInvalidNameTemplate(t *testing.T) {
   134  	testlib.CheckPath(t, "snapcraft")
   135  	folder := t.TempDir()
   136  	dist := filepath.Join(folder, "dist")
   137  	require.NoError(t, os.Mkdir(dist, 0o755))
   138  	ctx := testctx.NewWithCfg(config.Project{
   139  		ProjectName: "foo",
   140  		Dist:        dist,
   141  		Snapcrafts: []config.Snapcraft{
   142  			{
   143  				NameTemplate:     "foo_{{.Arch}",
   144  				Summary:          "test summary",
   145  				Description:      "test description",
   146  				Builds:           []string{"foo"},
   147  				ChannelTemplates: []string{"stable"},
   148  			},
   149  		},
   150  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   151  	addBinaries(t, ctx, "foo", dist)
   152  	testlib.RequireTemplateError(t, Pipe{}.Run(ctx))
   153  }
   154  
   155  func TestRunPipeWithName(t *testing.T) {
   156  	testlib.CheckPath(t, "snapcraft")
   157  	folder := t.TempDir()
   158  	dist := filepath.Join(folder, "dist")
   159  	require.NoError(t, os.Mkdir(dist, 0o755))
   160  	ctx := testctx.NewWithCfg(config.Project{
   161  		ProjectName: "testprojectname",
   162  		Dist:        dist,
   163  		Snapcrafts: []config.Snapcraft{
   164  			{
   165  				NameTemplate:     "foo_{{.Arch}}",
   166  				Name:             "testsnapname",
   167  				Base:             "core18",
   168  				License:          "MIT",
   169  				Summary:          "test summary",
   170  				Description:      "test description",
   171  				Builds:           []string{"foo"},
   172  				ChannelTemplates: []string{"stable"},
   173  			},
   174  		},
   175  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   176  	addBinaries(t, ctx, "foo", dist)
   177  	require.NoError(t, Pipe{}.Run(ctx))
   178  	yamlFile, err := os.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
   179  	require.NoError(t, err)
   180  	var metadata Metadata
   181  	err = yaml.Unmarshal(yamlFile, &metadata)
   182  	require.NoError(t, err)
   183  	require.Equal(t, "testsnapname", metadata.Name)
   184  	require.Equal(t, "core18", metadata.Base)
   185  	require.Equal(t, "MIT", metadata.License)
   186  	require.Equal(t, "foo", metadata.Apps["testsnapname"].Command)
   187  }
   188  
   189  func TestRunPipeMetadata(t *testing.T) {
   190  	testlib.CheckPath(t, "snapcraft")
   191  	folder := t.TempDir()
   192  	dist := filepath.Join(folder, "dist")
   193  	require.NoError(t, os.Mkdir(dist, 0o755))
   194  	ctx := testctx.NewWithCfg(config.Project{
   195  		ProjectName: "testprojectname",
   196  		Dist:        dist,
   197  		Snapcrafts: []config.Snapcraft{
   198  			{
   199  				Name:         "testprojectname",
   200  				NameTemplate: "foo_{{.Arch}}",
   201  				Summary:      "test summary",
   202  				Description:  "test description",
   203  				Layout: map[string]config.SnapcraftLayoutMetadata{
   204  					"/etc/testprojectname": {Bind: "$SNAP_DATA/etc"},
   205  				},
   206  				Apps: map[string]config.SnapcraftAppMetadata{
   207  					"before-foo": {
   208  						Before:  []string{"foo"},
   209  						Command: "foo",
   210  						Daemon:  "notify",
   211  					},
   212  					"after-foo": {
   213  						After:   []string{"foo"},
   214  						Command: "foo",
   215  						Daemon:  "notify",
   216  					},
   217  					"foo": {
   218  						Args:         "--foo --bar",
   219  						Adapter:      "foo_adapter",
   220  						Aliases:      []string{"dummy_alias"},
   221  						Autostart:    "foobar.desktop",
   222  						BusName:      "foo_busname",
   223  						CommandChain: []string{"foo_cmd_chain"},
   224  						CommonID:     "foo_common_id",
   225  						Completer:    "", // Separately tested in TestCompleter
   226  						Daemon:       "simple",
   227  						Desktop:      "foo_desktop",
   228  						Environment: map[string]interface{}{
   229  							"foo": "bar",
   230  						},
   231  						Extensions:  []string{"foo_extension"},
   232  						InstallMode: "disable",
   233  						Passthrough: map[string]interface{}{
   234  							"planet": "saturn",
   235  						},
   236  						Plugs:            []string{"home", "network", "network-bind", "personal-files"},
   237  						PostStopCommand:  "foo",
   238  						RefreshMode:      "endure",
   239  						ReloadCommand:    "foo",
   240  						RestartCondition: "always",
   241  						RestartDelay:     "42ms",
   242  						Slots:            []string{"foo_slot"},
   243  						Sockets: map[string]interface{}{
   244  							"sock": map[string]interface{}{
   245  								"listen-stream": "$SNAP_COMMON/socket",
   246  								"socket-group":  "socket-group",
   247  								"socket-mode":   0o640,
   248  							},
   249  						},
   250  						StartTimeout:    "43ms",
   251  						StopCommand:     "foo",
   252  						StopMode:        "sigterm",
   253  						StopTimeout:     "44ms",
   254  						Timer:           "00:00-24:00/24",
   255  						WatchdogTimeout: "45ms",
   256  					},
   257  				},
   258  				Plugs: map[string]interface{}{
   259  					"personal-files": map[string]interface{}{
   260  						"read": []string{"$HOME/test"},
   261  					},
   262  				},
   263  				Builds:           []string{"foo"},
   264  				ChannelTemplates: []string{"stable"},
   265  			},
   266  		},
   267  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   268  	addBinaries(t, ctx, "foo", dist)
   269  	require.NoError(t, Pipe{}.Run(ctx))
   270  	yamlFile, err := os.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
   271  	require.NoError(t, err)
   272  	var metadata Metadata
   273  	err = yaml.Unmarshal(yamlFile, &metadata)
   274  	require.NoError(t, err)
   275  	require.Equal(t, map[string]AppMetadata{
   276  		"before-foo": {
   277  			Before:  []string{"foo"},
   278  			Command: "foo",
   279  			Daemon:  "notify",
   280  		},
   281  		"after-foo": {
   282  			After:   []string{"foo"},
   283  			Command: "foo",
   284  			Daemon:  "notify",
   285  		},
   286  		"foo": {
   287  			Adapter:      "foo_adapter",
   288  			Aliases:      []string{"dummy_alias"},
   289  			Autostart:    "foobar.desktop",
   290  			BusName:      "foo_busname",
   291  			Command:      "foo --foo --bar",
   292  			CommandChain: []string{"foo_cmd_chain"},
   293  			CommonID:     "foo_common_id",
   294  			Completer:    "",
   295  			Daemon:       "simple",
   296  			Desktop:      "foo_desktop",
   297  			Environment: map[string]interface{}{
   298  				"foo": "bar",
   299  			},
   300  			Extensions:  []string{"foo_extension"},
   301  			InstallMode: "disable",
   302  			Passthrough: map[string]interface{}{
   303  				"planet": "saturn",
   304  			},
   305  			Plugs:            []string{"home", "network", "network-bind", "personal-files"},
   306  			PostStopCommand:  "foo",
   307  			RefreshMode:      "endure",
   308  			ReloadCommand:    "foo",
   309  			RestartCondition: "always",
   310  			RestartDelay:     "42ms",
   311  			Slots:            []string{"foo_slot"},
   312  			Sockets: map[string]interface{}{
   313  				"sock": map[string]interface{}{
   314  					"listen-stream": "$SNAP_COMMON/socket",
   315  					"socket-group":  "socket-group",
   316  					"socket-mode":   0o640,
   317  				},
   318  			},
   319  			StartTimeout:    "43ms",
   320  			StopCommand:     "foo",
   321  			StopMode:        "sigterm",
   322  			StopTimeout:     "44ms",
   323  			Timer:           "00:00-24:00/24",
   324  			WatchdogTimeout: "45ms",
   325  		},
   326  	}, metadata.Apps)
   327  	require.Equal(t, map[string]interface{}{"read": []interface{}{"$HOME/test"}}, metadata.Plugs["personal-files"])
   328  	require.Equal(t, "$SNAP_DATA/etc", metadata.Layout["/etc/testprojectname"].Bind)
   329  }
   330  
   331  func TestNoSnapcraftInPath(t *testing.T) {
   332  	t.Setenv("PATH", "")
   333  	ctx := testctx.NewWithCfg(config.Project{
   334  		Snapcrafts: []config.Snapcraft{
   335  			{
   336  				Summary:     "dummy",
   337  				Description: "dummy",
   338  			},
   339  		},
   340  	})
   341  	require.EqualError(t, Pipe{}.Run(ctx), ErrNoSnapcraft.Error())
   342  }
   343  
   344  func TestRunNoArguments(t *testing.T) {
   345  	testlib.CheckPath(t, "snapcraft")
   346  	folder := t.TempDir()
   347  	dist := filepath.Join(folder, "dist")
   348  	require.NoError(t, os.Mkdir(dist, 0o755))
   349  	ctx := testctx.NewWithCfg(config.Project{
   350  		ProjectName: "testprojectname",
   351  		Dist:        dist,
   352  		Snapcrafts: []config.Snapcraft{
   353  			{
   354  				NameTemplate: "foo_{{.Arch}}",
   355  				Summary:      "test summary",
   356  				Description:  "test description",
   357  				Apps: map[string]config.SnapcraftAppMetadata{
   358  					"foo": {
   359  						Daemon: "simple",
   360  						Args:   "",
   361  					},
   362  				},
   363  				Builds:           []string{"foo"},
   364  				ChannelTemplates: []string{"stable"},
   365  			},
   366  		},
   367  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   368  	addBinaries(t, ctx, "foo", dist)
   369  	require.NoError(t, Pipe{}.Run(ctx))
   370  	yamlFile, err := os.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
   371  	require.NoError(t, err)
   372  	var metadata Metadata
   373  	err = yaml.Unmarshal(yamlFile, &metadata)
   374  	require.NoError(t, err)
   375  	require.Equal(t, "foo", metadata.Apps["foo"].Command)
   376  }
   377  
   378  func TestCompleter(t *testing.T) {
   379  	testlib.CheckPath(t, "snapcraft")
   380  	folder := t.TempDir()
   381  	dist := filepath.Join(folder, "dist")
   382  	require.NoError(t, os.Mkdir(dist, 0o755))
   383  	ctx := testctx.NewWithCfg(config.Project{
   384  		ProjectName: "testprojectname",
   385  		Dist:        dist,
   386  		Snapcrafts: []config.Snapcraft{
   387  			{
   388  				NameTemplate: "foo_{{.Arch}}",
   389  				Summary:      "test summary",
   390  				Description:  "test description",
   391  				Apps: map[string]config.SnapcraftAppMetadata{
   392  					"foo": {
   393  						Daemon:    "simple",
   394  						Args:      "",
   395  						Completer: "testdata/foo-completer.bash",
   396  					},
   397  				},
   398  				Builds:           []string{"foo", "bar"},
   399  				ChannelTemplates: []string{"stable"},
   400  			},
   401  		},
   402  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   403  	addBinaries(t, ctx, "foo", dist)
   404  	addBinaries(t, ctx, "bar", dist)
   405  	require.NoError(t, Pipe{}.Run(ctx))
   406  	yamlFile, err := os.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
   407  	require.NoError(t, err)
   408  	var metadata Metadata
   409  	err = yaml.Unmarshal(yamlFile, &metadata)
   410  	require.NoError(t, err)
   411  	require.Equal(t, "foo", metadata.Apps["foo"].Command)
   412  	require.Equal(t, "testdata/foo-completer.bash", metadata.Apps["foo"].Completer)
   413  }
   414  
   415  func TestCommand(t *testing.T) {
   416  	testlib.CheckPath(t, "snapcraft")
   417  	folder := t.TempDir()
   418  	dist := filepath.Join(folder, "dist")
   419  	require.NoError(t, os.Mkdir(dist, 0o755))
   420  	ctx := testctx.NewWithCfg(config.Project{
   421  		ProjectName: "testprojectname",
   422  		Dist:        dist,
   423  		Snapcrafts: []config.Snapcraft{
   424  			{
   425  				NameTemplate: "foo_{{.Arch}}",
   426  				Summary:      "test summary",
   427  				Description:  "test description",
   428  				Apps: map[string]config.SnapcraftAppMetadata{
   429  					"foo": {
   430  						Daemon:  "simple",
   431  						Args:    "--bar custom command",
   432  						Command: "foo",
   433  					},
   434  				},
   435  				Builds:           []string{"foo"},
   436  				ChannelTemplates: []string{"stable"},
   437  			},
   438  		},
   439  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   440  	addBinaries(t, ctx, "foo", dist)
   441  	require.NoError(t, Pipe{}.Run(ctx))
   442  	yamlFile, err := os.ReadFile(filepath.Join(dist, "foo_amd64", "prime", "meta", "snap.yaml"))
   443  	require.NoError(t, err)
   444  	var metadata Metadata
   445  	err = yaml.Unmarshal(yamlFile, &metadata)
   446  	require.NoError(t, err)
   447  	require.Equal(t, "foo --bar custom command", metadata.Apps["foo"].Command)
   448  }
   449  
   450  func TestExtraFile(t *testing.T) {
   451  	testlib.CheckPath(t, "snapcraft")
   452  	folder := t.TempDir()
   453  	dist := filepath.Join(folder, "dist")
   454  	require.NoError(t, os.Mkdir(dist, 0o755))
   455  	ctx := testctx.NewWithCfg(config.Project{
   456  		ProjectName: "testprojectname",
   457  		Dist:        dist,
   458  		Snapcrafts: []config.Snapcraft{
   459  			{
   460  				NameTemplate: "foo_{{.Arch}}",
   461  				Summary:      "test summary",
   462  				Description:  "test description",
   463  				Files: []config.SnapcraftExtraFiles{
   464  					{
   465  						Source:      "testdata/extra-file.txt",
   466  						Destination: "a/b/c/extra-file.txt",
   467  						Mode:        0o755,
   468  					},
   469  					{
   470  						Source: "testdata/extra-file-2.txt",
   471  					},
   472  				},
   473  				Builds:           []string{"foo"},
   474  				ChannelTemplates: []string{"stable"},
   475  			},
   476  		},
   477  	}, testctx.WithCurrentTag("v1.2.3"), testctx.WithVersion("1.2.3"))
   478  	addBinaries(t, ctx, "foo", dist)
   479  	require.NoError(t, Pipe{}.Run(ctx))
   480  
   481  	apath := filepath.Join(dist, "foo_amd64", "prime", "a", "b", "c", "extra-file.txt")
   482  	bpath := filepath.Join(dist, "foo_amd64", "prime", "testdata", "extra-file-2.txt")
   483  	requireEqualFileContents(t, "testdata/extra-file.txt", apath)
   484  	requireEqualFileContents(t, "testdata/extra-file-2.txt", bpath)
   485  }
   486  
   487  func TestDefault(t *testing.T) {
   488  	ctx := testctx.NewWithCfg(config.Project{
   489  		Builds:     []config.Build{{ID: "foo"}},
   490  		Snapcrafts: []config.Snapcraft{{}},
   491  	})
   492  	require.NoError(t, Pipe{}.Default(ctx))
   493  	require.Equal(t, defaultNameTemplate, ctx.Config.Snapcrafts[0].NameTemplate)
   494  	require.Equal(t, []string{"foo"}, ctx.Config.Snapcrafts[0].Builds)
   495  	require.Equal(t, []string{"edge", "beta", "candidate", "stable"}, ctx.Config.Snapcrafts[0].ChannelTemplates)
   496  	require.Equal(t, "stable", ctx.Config.Snapcrafts[0].Grade)
   497  }
   498  
   499  func TestDefaultGradeTmpl(t *testing.T) {
   500  	ctx := testctx.NewWithCfg(config.Project{
   501  		Env:        []string{"Grade=devel"},
   502  		Builds:     []config.Build{{ID: "foo"}},
   503  		Snapcrafts: []config.Snapcraft{{Grade: "{{.Env.Grade}}"}},
   504  	})
   505  	require.NoError(t, Pipe{}.Default(ctx))
   506  	require.Equal(t, defaultNameTemplate, ctx.Config.Snapcrafts[0].NameTemplate)
   507  	require.Equal(t, []string{"foo"}, ctx.Config.Snapcrafts[0].Builds)
   508  	require.Equal(t, []string{"edge", "beta"}, ctx.Config.Snapcrafts[0].ChannelTemplates)
   509  	require.Equal(t, "devel", ctx.Config.Snapcrafts[0].Grade)
   510  }
   511  
   512  func TestDefaultGradeTmplError(t *testing.T) {
   513  	ctx := testctx.NewWithCfg(config.Project{
   514  		Builds:     []config.Build{{ID: "foo"}},
   515  		Snapcrafts: []config.Snapcraft{{Grade: "{{.Env.Grade}}"}},
   516  	})
   517  	testlib.RequireTemplateError(t, Pipe{}.Default(ctx))
   518  }
   519  
   520  func TestPublish(t *testing.T) {
   521  	ctx := testctx.New()
   522  	ctx.Artifacts.Add(&artifact.Artifact{
   523  		Name:   "mybin",
   524  		Path:   "nope.snap",
   525  		Goarch: "amd64",
   526  		Goos:   "linux",
   527  		Type:   artifact.PublishableSnapcraft,
   528  		Extra: map[string]interface{}{
   529  			releasesExtra: []string{"stable", "candidate"},
   530  		},
   531  	})
   532  	err := Pipe{}.Publish(ctx)
   533  	require.ErrorContains(t, err, "failed to push nope.snap package")
   534  }
   535  
   536  func TestDefaultSet(t *testing.T) {
   537  	ctx := testctx.NewWithCfg(config.Project{
   538  		Snapcrafts: []config.Snapcraft{
   539  			{
   540  				ID:           "devel",
   541  				NameTemplate: "foo",
   542  				Grade:        "devel",
   543  			},
   544  			{
   545  				ID:           "stable",
   546  				NameTemplate: "bar",
   547  				Grade:        "stable",
   548  			},
   549  		},
   550  	})
   551  	require.NoError(t, Pipe{}.Default(ctx))
   552  	require.Equal(t, "foo", ctx.Config.Snapcrafts[0].NameTemplate)
   553  	require.Equal(t, []string{"edge", "beta"}, ctx.Config.Snapcrafts[0].ChannelTemplates)
   554  	require.Equal(t, []string{"edge", "beta", "candidate", "stable"}, ctx.Config.Snapcrafts[1].ChannelTemplates)
   555  }
   556  
   557  func Test_processChannelsTemplates(t *testing.T) {
   558  	ctx := testctx.NewWithCfg(
   559  		config.Project{
   560  			Builds: []config.Build{
   561  				{
   562  					ID: "default",
   563  				},
   564  			},
   565  			Snapcrafts: []config.Snapcraft{
   566  				{
   567  					Name: "mybin",
   568  					ChannelTemplates: []string{
   569  						"{{.Major}}.{{.Minor}}/stable",
   570  						"stable",
   571  					},
   572  				},
   573  			},
   574  			Env: []string{"FOO=123"},
   575  		},
   576  		testctx.WithCommit("a1b2c3d4"),
   577  		testctx.WithCurrentTag("v1.0.0"),
   578  		testctx.WithSemver(1, 0, 0, ""),
   579  		testctx.WithVersion("1.0.0"),
   580  	)
   581  
   582  	require.NoError(t, Pipe{}.Default(ctx))
   583  	snap := ctx.Config.Snapcrafts[0]
   584  	require.Equal(t, "mybin", snap.Name)
   585  
   586  	channels, err := processChannelsTemplates(ctx, snap)
   587  	require.NoError(t, err)
   588  	require.Equal(t, []string{
   589  		"1.0/stable",
   590  		"stable",
   591  	}, channels)
   592  }
   593  
   594  func addBinaries(t *testing.T, ctx *context.Context, name, dist string) {
   595  	t.Helper()
   596  	for _, goos := range []string{"linux", "darwin"} {
   597  		for _, goarch := range []string{"amd64", "386", "arm"} {
   598  			binPath := filepath.Join(dist, name)
   599  			require.NoError(t, os.MkdirAll(filepath.Dir(binPath), 0o755))
   600  			f, err := os.Create(binPath)
   601  			require.NoError(t, err)
   602  			require.NoError(t, f.Close())
   603  			switch goarch {
   604  			case "arm":
   605  				ctx.Artifacts.Add(&artifact.Artifact{
   606  					Name:   "subdir/" + name,
   607  					Path:   binPath,
   608  					Goarch: goarch,
   609  					Goos:   goos,
   610  					Goarm:  "6",
   611  					Type:   artifact.Binary,
   612  					Extra: map[string]interface{}{
   613  						artifact.ExtraID: name,
   614  					},
   615  				})
   616  
   617  			case "amd64":
   618  				ctx.Artifacts.Add(&artifact.Artifact{
   619  					Name:    "subdir/" + name,
   620  					Path:    binPath,
   621  					Goarch:  goarch,
   622  					Goos:    goos,
   623  					Goamd64: "v1",
   624  					Type:    artifact.Binary,
   625  					Extra: map[string]interface{}{
   626  						artifact.ExtraID: name,
   627  					},
   628  				})
   629  			default:
   630  				ctx.Artifacts.Add(&artifact.Artifact{
   631  					Name:   "subdir/" + name,
   632  					Path:   binPath,
   633  					Goarch: goarch,
   634  					Goos:   goos,
   635  					Type:   artifact.Binary,
   636  					Extra: map[string]interface{}{
   637  						artifact.ExtraID: name,
   638  					},
   639  				})
   640  			}
   641  		}
   642  	}
   643  }
   644  
   645  func TestSeveralSnapssWithTheSameID(t *testing.T) {
   646  	ctx := testctx.NewWithCfg(config.Project{
   647  		Snapcrafts: []config.Snapcraft{
   648  			{
   649  				ID: "a",
   650  			},
   651  			{
   652  				ID: "a",
   653  			},
   654  		},
   655  	})
   656  	require.EqualError(t, Pipe{}.Default(ctx), "found 2 snapcrafts with the ID 'a', please fix your config")
   657  }
   658  
   659  func Test_isValidArch(t *testing.T) {
   660  	tests := []struct {
   661  		arch string
   662  		want bool
   663  	}{
   664  		{"s390x", true},
   665  		{"ppc64el", true},
   666  		{"arm64", true},
   667  		{"armhf", true},
   668  		{"i386", true},
   669  		{"mips", false},
   670  		{"armel", false},
   671  	}
   672  	for _, tt := range tests {
   673  		t.Run(tt.arch, func(t *testing.T) {
   674  			require.Equal(t, tt.want, isValidArch(tt.arch))
   675  		})
   676  	}
   677  }
   678  
   679  func TestSkip(t *testing.T) {
   680  	t.Run("skip", func(t *testing.T) {
   681  		require.True(t, Pipe{}.Skip(testctx.New()))
   682  	})
   683  	t.Run("skip flag", func(t *testing.T) {
   684  		ctx := testctx.NewWithCfg(config.Project{
   685  			Snapcrafts: []config.Snapcraft{
   686  				{},
   687  			},
   688  		}, testctx.Skip(skips.Snapcraft))
   689  		require.True(t, Pipe{}.Skip(ctx))
   690  	})
   691  	t.Run("dont skip", func(t *testing.T) {
   692  		ctx := testctx.NewWithCfg(config.Project{
   693  			Snapcrafts: []config.Snapcraft{
   694  				{},
   695  			},
   696  		})
   697  		require.False(t, Pipe{}.Skip(ctx))
   698  	})
   699  }
   700  
   701  func TestDependencies(t *testing.T) {
   702  	ctx := testctx.NewWithCfg(config.Project{
   703  		Snapcrafts: []config.Snapcraft{
   704  			{},
   705  		},
   706  	})
   707  	require.Equal(t, []string{"snapcraft"}, Pipe{}.Dependencies(ctx))
   708  }
   709  
   710  func requireEqualFileContents(tb testing.TB, a, b string) {
   711  	tb.Helper()
   712  	eq, err := gio.EqualFileContents(a, b)
   713  	require.NoError(tb, err)
   714  	require.True(tb, eq, "%s != %s", a, b)
   715  }