Skip to content

Commit

Permalink
Merge pull request #2398 from andydotxyz/feature/metadata
Browse files Browse the repository at this point in the history
Feature/metadata
  • Loading branch information
andydotxyz committed Aug 27, 2021
2 parents 0a3fe4c + c42f200 commit 74a0fbc
Show file tree
Hide file tree
Showing 29 changed files with 4,128 additions and 5 deletions.
35 changes: 32 additions & 3 deletions cmd/fyne/internal/commands/package.go
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/pkg/errors"
"github.com/urfave/cli/v2"

"fyne.io/fyne/v2/cmd/fyne/internal/metadata"
"fyne.io/fyne/v2/cmd/fyne/internal/util"
)

Expand Down Expand Up @@ -74,7 +75,7 @@ func Package() *cli.Command {
&cli.StringFlag{
Name: "icon",
Usage: "The name of the application icon file.",
Value: "Icon.png",
Value: "",
Destination: &p.icon,
},
&cli.StringFlag{
Expand Down Expand Up @@ -124,7 +125,7 @@ func (p *Packager) AddFlags() {
flag.StringVar(&p.exe, "executable", "", "Specify an existing binary instead of building before package")
flag.StringVar(&p.srcDir, "sourceDir", "", "The directory to package, if executable is not set")
flag.StringVar(&p.name, "name", "", "The name of the application, default is the executable file name")
flag.StringVar(&p.icon, "icon", "Icon.png", "The name of the application icon file")
flag.StringVar(&p.icon, "icon", "", "The name of the application icon file")
flag.StringVar(&p.appID, "appID", "", "For ios or darwin targets an appID is required, for ios this must \nmatch a valid provisioning profile")
flag.StringVar(&p.appVersion, "appVersion", "", "Version number in the form x, x.y or x.y.z semantic version")
flag.IntVar(&p.appBuild, "appBuild", 0, "Build number, should be greater than 0 and incremented for each build")
Expand Down Expand Up @@ -170,7 +171,12 @@ func (p *Packager) Package() error {
return err
}

return nil
data, err := metadata.LoadStandard(p.srcDir)
if err != nil {
return nil // no metadata to update
}
data.Details.Build++
return metadata.SaveStandard(data, p.srcDir)
}

func (p *Packager) buildPackage() error {
Expand Down Expand Up @@ -252,6 +258,11 @@ func (p *Packager) validate() error {
"Change directory to the main package and try again.")
}

data, err := metadata.LoadStandard(p.srcDir)
if err == nil {
mergeMetadata(p, data)
}

exeName := calculateExeName(p.srcDir, p.os)

if p.exe == "" {
Expand Down Expand Up @@ -298,6 +309,24 @@ func isValidVersion(ver string) bool {
return true
}

func mergeMetadata(p *Packager, data *metadata.FyneApp) {
if p.icon == "" {
p.icon = data.Details.Icon
}
if p.name == "" {
p.name = data.Details.Name
}
if p.appID == "" {
p.appID = data.Details.ID
}
if p.appVersion == "" {
p.appVersion = data.Details.Version
}
if p.appBuild == 0 {
p.appBuild = data.Details.Build
}
}

func validateAppID(appID, os, name string, release bool) (string, error) {
// old darwin compatibility
if os == "darwin" {
Expand Down
18 changes: 18 additions & 0 deletions cmd/fyne/internal/commands/package_test.go
Expand Up @@ -4,6 +4,8 @@ import (
"testing"

"github.com/stretchr/testify/assert"

"fyne.io/fyne/v2/cmd/fyne/internal/metadata"
)

func Test_calculateExeName(t *testing.T) {
Expand All @@ -29,6 +31,22 @@ func Test_isValidVersion(t *testing.T) {
assert.False(t, isValidVersion("1..2"))
}

func Test_MergeMetata(t *testing.T) {
p := &Packager{appVersion: "v0.1"}
data := &metadata.FyneApp{
Details: metadata.AppDetails{
Icon: "test.png",
Build: 3,
Version: "v0.0.1",
},
}

mergeMetadata(p, data)
assert.Equal(t, "v0.1", p.appVersion)
assert.Equal(t, 3, p.appBuild)
assert.Equal(t, "test.png", p.icon)
}

func Test_validateAppID(t *testing.T) {
id, err := validateAppID("myApp", "windows", "myApp", false)
assert.Nil(t, err)
Expand Down
9 changes: 7 additions & 2 deletions cmd/fyne/internal/commands/release.go
Expand Up @@ -112,7 +112,7 @@ func Release() *cli.Command {
&cli.StringFlag{
Name: "icon",
Usage: "The name of the application icon file.",
Value: "Icon.png",
Value: "",
Destination: &r.icon,
},
},
Expand All @@ -137,7 +137,7 @@ type Releaser struct {
func (r *Releaser) AddFlags() {
flag.StringVar(&r.os, "os", "", "The operating system to target (android, android/arm, android/arm64, android/amd64, android/386, darwin, freebsd, ios, linux, netbsd, openbsd, windows)")
flag.StringVar(&r.name, "name", "", "The name of the application, default is the executable file name")
flag.StringVar(&r.icon, "icon", "Icon.png", "The name of the application icon file")
flag.StringVar(&r.icon, "icon", "", "The name of the application icon file")
flag.StringVar(&r.appID, "appID", "", "For ios or darwin targets an appID is required, for ios this must \nmatch a valid provisioning profile")
flag.StringVar(&r.appVersion, "appVersion", "", "Version number in the form x, x.y or x.y.z semantic version")
flag.IntVar(&r.appBuild, "appBuild", 0, "Build number, should be greater than 0 and incremented for each build")
Expand Down Expand Up @@ -398,6 +398,11 @@ func (r *Releaser) validate() error {
if r.os == "" {
r.os = targetOS()
}
err := r.Packager.validate()
if err != nil {
return err
}

if util.IsMobile(r.os) || r.os == "windows" {
if r.appVersion == "" { // Here it is required, if provided then package validate will check format
return errors.New("missing required -appVersion parameter")
Expand Down
15 changes: 15 additions & 0 deletions cmd/fyne/internal/metadata/data.go
@@ -0,0 +1,15 @@
package metadata

// FyneApp describes the top level metadata for building a fyne application
type FyneApp struct {
Website string `toml:",omitempty"`
Details AppDetails
}

// AppDetails describes the build information, this group may be OS or arch specific
type AppDetails struct {
Icon string `toml:",omitempty"`
Name, ID string `toml:",omitempty"`
Version string `toml:",omitempty"`
Build int `toml:",omitempty"`
}
39 changes: 39 additions & 0 deletions cmd/fyne/internal/metadata/load.go
@@ -0,0 +1,39 @@
package metadata

import (
"io"
"io/ioutil"
"os"
"path/filepath"

"github.com/BurntSushi/toml"
)

// Load attempts to read a FyneApp metadata from the provided reader.
// If this cannot be done an error will be returned.
func Load(r io.Reader) (*FyneApp, error) {
str, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}

var data FyneApp
if _, err := toml.Decode(string(str), &data); err != nil {
return nil, err
}

return &data, nil
}

// LoadStandard attempts to read a FyneApp metadata from the `FyneApp.toml` file in the specified dir.
// If the file cannot be found or parsed an error will be returned.
func LoadStandard(dir string) (*FyneApp, error) {
path := filepath.Join(dir, "FyneApp.toml")
r, err := os.Open(path)
if err != nil {
return nil, err
}

defer r.Close()
return Load(r)
}
21 changes: 21 additions & 0 deletions cmd/fyne/internal/metadata/load_test.go
@@ -0,0 +1,21 @@
package metadata

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLoadAppMetadata(t *testing.T) {
r, err := os.Open("./testdata/FyneApp.toml")
assert.Nil(t, err)
defer r.Close()

data, err := Load(r)
assert.Nil(t, err)
assert.Equal(t, "https://apps.fyne.io", data.Website)
assert.Equal(t, "io.fyne.fyne", data.Details.ID)
assert.Equal(t, "v1.0", data.Details.Version)
assert.Equal(t, 1, data.Details.Build)
}
37 changes: 37 additions & 0 deletions cmd/fyne/internal/metadata/save.go
@@ -0,0 +1,37 @@
package metadata

import (
"bytes"
"io"
"os"
"path/filepath"

"github.com/BurntSushi/toml"
)

// Save attempts to write a FyneApp metadata to the provided writer.
// If the encoding fails an error will be returned.
func Save(f *FyneApp, w io.Writer) error {
var buf bytes.Buffer
e := toml.NewEncoder(&buf)
err := e.Encode(f)
if err != nil {
return err
}

_, err = w.Write(buf.Bytes())
return err
}

// SaveStandard attempts to save a FyneApp metadata to the `FyneApp.toml` file in the specified dir.
// If the file cannot be written or encoding fails an error will be returned.
func SaveStandard(f *FyneApp, dir string) error {
path := filepath.Join(dir, "FyneApp.toml")
w, err := os.Create(path)
if err != nil {
return err
}

defer w.Close()
return Save(f, w)
}
37 changes: 37 additions & 0 deletions cmd/fyne/internal/metadata/save_test.go
@@ -0,0 +1,37 @@
package metadata

import (
"os"
"testing"

"github.com/stretchr/testify/assert"
)

func TestSaveAppMetadata(t *testing.T) {
r, err := os.Open("./testdata/FyneApp.toml")
assert.Nil(t, err)
data, err := Load(r)
_ = r.Close()
assert.Nil(t, err)
assert.Equal(t, 1, data.Details.Build)

data.Details.Build++

versionPath := "./testdata/Version.toml"
w, err := os.Create(versionPath)
assert.Nil(t, err)
err = Save(data, w)
assert.Nil(t, err)
defer func() {
os.Remove(versionPath)
}()
_ = w.Close()

r, err = os.Open(versionPath)
assert.Nil(t, err)
defer r.Close()

data2, err := Load(r)
assert.Nil(t, err)
assert.Equal(t, 2, data2.Details.Build)
}
9 changes: 9 additions & 0 deletions cmd/fyne/internal/metadata/testdata/FyneApp.toml
@@ -0,0 +1,9 @@
Website = "https://apps.fyne.io"

[Details]
Name = "Fyne App"
ID = "io.fyne.fyne"
Icon = "https://conf.fyne.io/assets/img/fyne.png"
Version = "v1.0"
Build = 1

1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -3,6 +3,7 @@ module fyne.io/fyne/v2
go 1.12

require (
github.com/BurntSushi/toml v0.4.1
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9
github.com/akavel/rsrc v0.8.0 // indirect
github.com/fredbi/uri v0.0.0-20181227131451-3dcfdacbaaf3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
@@ -1,4 +1,6 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9 h1:1ltqoej5GtaWF8jaiA49HwsZD459jqm9YFz9ZtMFpQA=
github.com/Kodeworks/golang-image-ico v0.0.0-20141118225523-73f0f4cfade9/go.mod h1:7uhhqiBaR4CpN0k9rMjOtjpcfGd6DG2m04zQxKnWQ0I=
github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw=
Expand Down
2 changes: 2 additions & 0 deletions vendor/github.com/BurntSushi/toml/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vendor/github.com/BurntSushi/toml/COMPATIBLE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/BurntSushi/toml/COPYING

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 74a0fbc

Please sign in to comment.