Skip to content

Commit

Permalink
client, daemon, cmd: support for snap --version (#1197)
Browse files Browse the repository at this point in the history
  • Loading branch information
chipaca committed May 23, 2016
1 parent cc4ed22 commit d8fbd57
Show file tree
Hide file tree
Showing 19 changed files with 115 additions and 82 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ integration-tests/data/output/
share
tags
.coverage
cmd/version_generated.go
*~
21 changes: 16 additions & 5 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,20 @@ func (client *Client) doAsync(method, path string, query url.Values, headers map
return rsp.Change, nil
}

func (client *Client) ServerVersion() (string, error) {
sysInfo, err := client.SysInfo()
if err != nil {
return "unknown", err
}

version := sysInfo.Version
if version == "" {
version = "unknown"
}

return fmt.Sprintf("%s (series %s)", version, sysInfo.Series), nil
}

// A response produced by the REST API will usually fit in this
// (exceptions are the icons/ endpoints obvs)
type response struct {
Expand Down Expand Up @@ -232,11 +246,8 @@ func IsTwoFactorError(err error) bool {

// SysInfo holds system information
type SysInfo struct {
Flavor string `json:"flavor"`
Release string `json:"release"`
DefaultChannel string `json:"default-channel"`
APICompatibility string `json:"api-compat"`
Store string `json:"store,omitempty"`
Series string `json:"series,omitempty"`
Version string `json:"version,omitempty"`
}

func (rsp *response) err() error {
Expand Down
35 changes: 6 additions & 29 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,6 @@ func (cs *clientSuite) TestNewPanics(c *check.C) {
client.New(&client.Config{BaseURL: ":"})
}, check.PanicMatches, `cannot parse server base URL: ":" \(parse :: missing protocol scheme\)`)
}

func (cs *clientSuite) TestNewCustomURL(c *check.C) {
f := func(w http.ResponseWriter, r *http.Request) {
c.Check(r.URL.Path, check.Equals, "/v2/system-info")
c.Check(r.URL.RawQuery, check.Equals, "")
fmt.Fprintln(w, `{"type":"sync", "result":{"store":"X"}}`)
}
srv := httptest.NewServer(http.HandlerFunc(f))
defer srv.Close()

cli := client.New(&client.Config{BaseURL: srv.URL})
c.Assert(cli, check.Not(check.IsNil))
si, err := cli.SysInfo()
c.Check(err, check.IsNil)
c.Check(si.Store, check.Equals, "X")
}

func (cs *clientSuite) TestClientDoReportsErrors(c *check.C) {
cs.err = errors.New("ouchie")
err := cs.cli.Do("GET", "/", nil, nil, nil)
Expand Down Expand Up @@ -148,19 +131,13 @@ func (cs *clientSuite) TestClientSetsAuthorization(c *check.C) {

func (cs *clientSuite) TestClientSysInfo(c *check.C) {
cs.rsp = `{"type": "sync", "result":
{"flavor": "f",
"release": "r",
"default-channel": "dc",
"api-compat": "42",
"store": "store"}}`
{"series": "16",
"version": "2"}}`
sysInfo, err := cs.cli.SysInfo()
c.Check(err, check.IsNil)
c.Check(sysInfo, check.DeepEquals, &client.SysInfo{
Flavor: "f",
Release: "r",
DefaultChannel: "dc",
APICompatibility: "42",
Store: "store",
Version: "2",
Series: "16",
})
}

Expand All @@ -175,7 +152,7 @@ func (cs *clientSuite) TestClientIntegration(c *check.C) {
c.Check(r.URL.Path, check.Equals, "/v2/system-info")
c.Check(r.URL.RawQuery, check.Equals, "")

fmt.Fprintln(w, `{"type":"sync", "result":{"store":"X"}}`)
fmt.Fprintln(w, `{"type":"sync", "result":{"series":"42"}}`)
}

srv := &httptest.Server{
Expand All @@ -188,7 +165,7 @@ func (cs *clientSuite) TestClientIntegration(c *check.C) {
cli := client.New(nil)
si, err := cli.SysInfo()
c.Check(err, check.IsNil)
c.Check(si.Store, check.Equals, "X")
c.Check(si.Series, check.Equals, "42")
}

func (cs *clientSuite) TestClientReportsOpError(c *check.C) {
Expand Down
3 changes: 3 additions & 0 deletions cmd/snap/cmd_connect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ the gadget snap, the kernel snap, and then the os snap, in that order. The
first of these snaps that has a matching plug name is used and the command
proceeds as above.
Application Options:
--version print the version and exit
Help Options:
-h, --help Show this help message
`
Expand Down
3 changes: 3 additions & 0 deletions cmd/snap/cmd_disconnect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ $ snap disconnect <snap>
Disconnects all plugs from the provided snap.
Application Options:
--version print the version and exit
Help Options:
-h, --help Show this help message
`
Expand Down
3 changes: 3 additions & 0 deletions cmd/snap/cmd_help_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ The snap tool interacts with the snapd daemon to control the snappy software
platform.
Application Options:
+--version +print the version and exit
Help Options:
+-h, --help +Show this help message
Expand Down
3 changes: 3 additions & 0 deletions cmd/snap/cmd_interfaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ $ snap interfaces -i=<interface> [<snap>]
Filters the complete output so only plugs and/or slots matching the provided
details are listed.
Application Options:
--version print the version and exit
Help Options:
-h, --help Show this help message
Expand Down
14 changes: 13 additions & 1 deletion cmd/snap/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"strings"

"github.com/ubuntu-core/snappy/client"
"github.com/ubuntu-core/snappy/cmd"
"github.com/ubuntu-core/snappy/i18n"
"github.com/ubuntu-core/snappy/logger"

"github.com/jessevdk/go-flags"
Expand All @@ -39,7 +41,7 @@ var (
)

type options struct {
// No global options yet
Version func() `long:"version" description:"print the version and exit"`
}

var optionsData options
Expand Down Expand Up @@ -92,6 +94,16 @@ type parserSetter interface {
// Since commands have local state a fresh parser is required to isolate tests
// from each other.
func Parser() *flags.Parser {
optionsData.Version = func() {
cv, err := Client().ServerVersion()
if err != nil {
cv = i18n.G("unavailable")
}

fmt.Fprintf(Stdout, "snap %s\nsnapd %s\n", cmd.Version, cv)

os.Exit(0)
}
parser := flags.NewParser(&optionsData, flags.HelpFlag|flags.PassDoubleDash)
parser.ShortDescription = "Tool to interact with snaps"
parser.LongDescription = `
Expand Down
3 changes: 2 additions & 1 deletion cmd/snapd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"os/signal"
"syscall"

"github.com/ubuntu-core/snappy/cmd"
"github.com/ubuntu-core/snappy/daemon"
"github.com/ubuntu-core/snappy/logger"
)
Expand All @@ -48,10 +49,10 @@ func run() error {
if err != nil {
return err
}

if err := d.Init(); err != nil {
return err
}
d.Version = cmd.Version

d.Start()

Expand Down
25 changes: 25 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// -*- Mode: Go; indent-tabs-mode: t -*-

/*
* Copyright (C) 2016 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package cmd

//go:generate mkversion.sh

// will be overwritten at build-time via mkversion.sh
var Version = "unknown"
3 changes: 2 additions & 1 deletion daemon/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ func tbd(c *Command, r *http.Request, user *auth.UserState) Response {

func sysInfo(c *Command, r *http.Request, user *auth.UserState) Response {
m := map[string]string{
"series": release.Series,
"series": release.Series,
"version": c.d.Version,
}

return SyncResponse(m, nil)
Expand Down
24 changes: 4 additions & 20 deletions daemon/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,31 +397,15 @@ func (s *apiSuite) TestSysInfo(c *check.C) {
rec := httptest.NewRecorder()
c.Check(sysInfoCmd.Path, check.Equals, "/v2/system-info")

sysInfoCmd.GET(sysInfoCmd, nil, nil).ServeHTTP(rec, nil)
c.Check(rec.Code, check.Equals, 200)
c.Check(rec.HeaderMap.Get("Content-Type"), check.Equals, "application/json")

expected := map[string]interface{}{
"series": "16",
}
var rsp resp
c.Assert(json.Unmarshal(rec.Body.Bytes(), &rsp), check.IsNil)
c.Check(rsp.Status, check.Equals, 200)
c.Check(rsp.Type, check.Equals, ResponseTypeSync)
c.Check(rsp.Result, check.DeepEquals, expected)
}

func (s *apiSuite) TestSysInfoStore(c *check.C) {
rec := httptest.NewRecorder()
c.Check(sysInfoCmd.Path, check.Equals, "/v2/system-info")

s.mkGadget(c, "some-store")
s.daemon(c).Version = "42b1"

sysInfoCmd.GET(sysInfoCmd, nil, nil).ServeHTTP(rec, nil)
c.Check(rec.Code, check.Equals, 200)
c.Check(rec.HeaderMap.Get("Content-Type"), check.Equals, "application/json")

expected := map[string]interface{}{
"series": "16",
"series": "16",
"version": "42b1",
}
var rsp resp
c.Assert(json.Unmarshal(rec.Body.Bytes(), &rsp), check.IsNil)
Expand Down
1 change: 1 addition & 0 deletions daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (

// A Daemon listens for requests and routes them to the right command
type Daemon struct {
Version string
overlord *overlord.Overlord
listener net.Listener
tomb tomb.Tomb
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Priority: optional
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Build-Depends: bash-completion,
debhelper (>= 9),
dh-golang,
dh-golang (>=1.7),
dh-systemd,
fakeroot,
gettext,
Expand Down
18 changes: 6 additions & 12 deletions debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ export DH_OPTIONS
export DH_GOPKG := github.com/ubuntu-core/snappy
#export DEB_BUILD_OPTIONS=nocheck
export DH_GOLANG_EXCLUDES=integration-tests
export DH_GOLANG_GO_GENERATE=1

# we need the builddir; is there a simpler way to get it?
BUILDDIR:=${CURDIR}/obj-$(shell dpkg-architecture -qDEB_TARGET_GNU_TYPE)

export PATH:=${PATH}:${CURDIR}

RELEASE = $(shell lsb_release -c -s)

Expand Down Expand Up @@ -54,18 +60,6 @@ override_dh_systemd_start:
-psnapd \
snapd.socket

# we need the builddir; is there a simpler way to get it?
BUILDDIR:=${CURDIR}/obj-$(shell dpkg-architecture -qDEB_TARGET_GNU_TYPE)

override_dh_auto_build:
dh_auto_build
# this will update the i18n stuff using our build-in xgettext-go
if [ "$(RELEASE)" = "vivid" ]; then\
GOPATH=${BUILDDIR} ./update-pot;\
else\
GOPATH=${BUILDDIR} go generate ./i18n;\
fi;

override_dh_auto_install: snap.8
dh_auto_install -O--buildsystem=golang
# we do not need this in the package, its just needed during build
Expand Down
2 changes: 1 addition & 1 deletion i18n/i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

package i18n

//go:generate ../update-pot
//go:generate update-pot

import (
"github.com/gosexy/gettext"
Expand Down
18 changes: 18 additions & 0 deletions mkversion.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
set -e

if [ -z "$GOPACKAGE" ]; then
# not being run from 'go generate'
cd "$(dirname "$0")"/cmd
fi

v="$( git describe --dirty --always | sed -e 's/-/+git/;y/-/./' )"

cat <<EOF > version_generated.go
// generated by mkversion.sh; do not edit
package cmd
func init() {
Version = "$v"
}
EOF
5 changes: 4 additions & 1 deletion po/snappy.pot
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: snappy\n"
"Report-Msgid-Bugs-To: snappy-devel@lists.ubuntu.com\n"
"POT-Creation-Date: 2016-05-19 09:54+0100\n"
"POT-Creation-Date: 2016-05-23 14:43+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -353,6 +353,9 @@ msgstr ""
msgid "no interfaces found"
msgstr ""

msgid "unavailable"
msgstr ""

#, c-format
msgid "unsupported shell %v"
msgstr ""
Expand Down
13 changes: 3 additions & 10 deletions run-checks
Original file line number Diff line number Diff line change
Expand Up @@ -108,16 +108,9 @@ if [ ! -z "$STATIC" ]; then
# cmd/* test sources are tagged so they are not included in
# special integration test builds
echo Checking 'cmd/*/*_test.go' build tagging
bad=""
for cmd in cmd/* ; do
nottagged=$(ls ${cmd}/*_test.go|grep -v integration_coverage_test|grep -v -F "$(grep -l '!integrationcoverage' ${cmd}/*_test.go)" || true)

if [ -n "${nottagged}" ] ; then
echo these ${cmd} test files miss the '!integrationcoverage' tag: ${nottagged}
bad=1
fi
done
if [ -n "${bad}" ] ; then
nottagged=$(grep -r --include '*_test.go' --exclude integration_coverage_test.go -L '!integrationcoverage' cmd/*/)
if [ -n "${nottagged}" ] ; then
echo these test files miss the '!integrationcoverage' tag: ${nottagged}
exit 1
fi

Expand Down

0 comments on commit d8fbd57

Please sign in to comment.