Merge lp:~mvo/snappy/snappy-console into lp:~snappy-dev/snappy/snappy-moved-to-github

Proposed by Michael Vogt on 2015-06-16
Status: Merged
Approved by: Michael Vogt on 2015-09-18
Approved revision: 524
Merged at revision: 710
Proposed branch: lp:~mvo/snappy/snappy-console
Merge into: lp:~snappy-dev/snappy/snappy-moved-to-github
Prerequisite: lp:~mvo/snappy/snappy-with-decorator2
Diff against target: 255 lines (+224/-0)
4 files modified
cmd/snappy/cmd_console.go (+165/-0)
cmd/snappy/cmd_console_test.go (+57/-0)
debian/control (+1/-0)
dependencies.tsv (+1/-0)
To merge this branch: bzr merge lp:~mvo/snappy/snappy-console
Reviewer Review Type Date Requested Status
Michael Vogt Approve on 2015-09-18
Leo Arias Needs Fixing on 2015-06-25
John Lenton 2015-06-16 Approve on 2015-06-16
Snappy Tarmac continuous-integration Pending
Federico Gimenez continuous-integration Pending
Review via email: mp+262061@code.launchpad.net

This proposal supersedes a proposal from 2015-06-15.

Commit Message

Add new "snappy shell" command.

Description of the Change

This is a bit of a proof-of-concept and needs additional work to package the golang-liner package for debian.

It will add a new "snappy console" command that will run a minimal readline like console to run commands.

To post a comment you must log in.
John Lenton (chipaca) wrote :

Lovely. Obviously needs work, but lovely. You want to land this? I'm +1 for it.

review: Approve
Leo Arias (elopio) wrote :

One detail to take into account is that liner has 13.7% of test coverage.
We should unit test our code and increase the liner unit test coverage, or cover both with integration or functional tests. Or well, there's always the option of just accepting the risk of adding untested dependencies to our project.

Michael Vogt (mvo) wrote :

@Leo Thanks! I haven't actually checked the coverage for liner, that is a good point indeed. I looked into the coverage problems and it seems a lot of it is because of the way it deals with input, I pushed https://github.com/mvo5/liner/commit/485491f62cf2779cd5cc60a05101472576c597ec that covers some more input classes as a starting point. It seems improving coverage is relatively straightforward. Fwiw, I'm not sure the alternatives are better, AFAICS the C libreadline (which is what the others are based on) is not unit tested at all.

Leo Arias (elopio) wrote :

A small detail found by vet:

$ go vet ./cmd/snappy/
cmd/snappy/cmd_console.go:96: unreachable code
exit status 1

review: Needs Fixing
Leo Arias (elopio) wrote :

Also, lint doesn't like it.

Lint complains:
cmd/snappy/cmd_console.go:76:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)

review: Needs Fixing
Michael Vogt (mvo) wrote :

Thanks! I fixed the vet/lint issues.

Michael Vogt (mvo) wrote :

I put this up again, during the Lexington sprint we talked about that we want a snappy console experience. However, feel free to reject if you feel like its not mature enough yet.

lp:~mvo/snappy/snappy-console updated on 2015-09-18
524. By Michael Vogt on 2015-09-18

merged lp:snappy

Michael Vogt (mvo) wrote :

All vet/lint issues should be resolved, so I will approve based on the approve from John in the first comment.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'cmd/snappy/cmd_console.go'
2--- cmd/snappy/cmd_console.go 1970-01-01 00:00:00 +0000
3+++ cmd/snappy/cmd_console.go 2015-09-18 05:57:08 +0000
4@@ -0,0 +1,165 @@
5+// -*- Mode: Go; indent-tabs-mode: t -*-
6+
7+/*
8+ * Copyright (C) 2014-2015 Canonical Ltd
9+ *
10+ * This program is free software: you can redistribute it and/or modify
11+ * it under the terms of the GNU General Public License version 3 as
12+ * published by the Free Software Foundation.
13+ *
14+ * This program is distributed in the hope that it will be useful,
15+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ * GNU General Public License for more details.
18+ *
19+ * You should have received a copy of the GNU General Public License
20+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21+ *
22+ */
23+
24+package main
25+
26+import (
27+ "fmt"
28+ "io"
29+ "os"
30+ "os/exec"
31+ "strings"
32+
33+ "github.com/peterh/liner"
34+
35+ "launchpad.net/snappy/logger"
36+)
37+
38+// for testing
39+var stdout io.Writer = os.Stdout
40+
41+type cmdConsole struct {
42+ repl *liner.State
43+ extraCommands []consoleCommand
44+}
45+
46+func init() {
47+ _, err := parser.AddCommand("console",
48+ "Run snappy console interface",
49+ "Run snappy console interface",
50+ &cmdConsole{})
51+ if err != nil {
52+ logger.Panicf("Unable to console: %v", err)
53+ }
54+}
55+
56+func (x *cmdConsole) Execute(args []string) error {
57+ return x.doConsole()
58+}
59+
60+type consoleCommand struct {
61+ name string
62+ fn func(line string) error
63+}
64+
65+func (x *cmdConsole) snappyCompleter(line string) (c []string) {
66+ // FIXME: add smartz and also complete arguments of
67+ // commands
68+ for _, cmd := range parser.Commands() {
69+ if strings.HasPrefix(cmd.Name, strings.ToLower(line)) {
70+ c = append(c, cmd.Name)
71+ }
72+ }
73+ for _, cmd := range x.extraCommands {
74+ if strings.HasPrefix(cmd.name, line) {
75+ c = append(c, cmd.name)
76+ }
77+ }
78+
79+ return c
80+}
81+
82+func (x *cmdConsole) initConsole() error {
83+ // FIXME: add history (ReadHistory/WriteHistory)
84+
85+ x.extraCommands = []consoleCommand{
86+ {"help", x.doHelp},
87+ {"shell", x.doShell},
88+ }
89+
90+ x.repl = liner.NewLiner()
91+ x.repl.SetCompleter(x.snappyCompleter)
92+
93+ return nil
94+}
95+
96+func (x *cmdConsole) CloseConsole() {
97+ x.repl.Close()
98+}
99+
100+func (x *cmdConsole) PrintWelcomeMessage() {
101+ fmt.Println("Welcome to the snappy console")
102+ fmt.Println("Type 'help' for help")
103+ fmt.Println("Type 'shell' for entering a shell")
104+}
105+
106+func (x *cmdConsole) doShell(line string) error {
107+ // restore terminal for the shell
108+ x.CloseConsole()
109+ defer x.initConsole()
110+
111+ sh := os.Getenv("SHELL")
112+ if sh == "" {
113+ sh = "/bin/sh"
114+ }
115+ cmd := exec.Command(sh)
116+ cmd.Stdin = os.Stdin
117+ cmd.Stdout = os.Stdout
118+ cmd.Stderr = os.Stderr
119+ if err := cmd.Run(); err != nil {
120+ return err
121+ }
122+
123+ return nil
124+}
125+
126+func (x *cmdConsole) doHelp(line string) error {
127+ line = strings.TrimPrefix(line, "help")
128+ line = strings.TrimSpace(line)
129+ parser.Active = nil
130+ // find subcmd
131+ for _, cmd := range parser.Commands() {
132+ if strings.HasPrefix(line, cmd.Name) {
133+ parser.Active = cmd
134+ break
135+ }
136+ }
137+ parser.WriteHelp(stdout)
138+
139+ return nil
140+}
141+
142+func (x *cmdConsole) doConsole() error {
143+ x.initConsole()
144+ defer x.CloseConsole()
145+ x.PrintWelcomeMessage()
146+
147+outer:
148+ for {
149+ line, err := x.repl.Prompt("> ")
150+ if err != nil {
151+ return err
152+ }
153+ x.repl.AppendHistory(line)
154+
155+ for _, cmd := range x.extraCommands {
156+ if strings.HasPrefix(line, cmd.name) {
157+ if err := cmd.fn(line); err != nil {
158+ fmt.Println(err)
159+ }
160+ continue outer
161+ }
162+ }
163+
164+ if _, err = parser.ParseArgs(strings.Fields(line)); err != nil {
165+ fmt.Println(err)
166+ }
167+
168+ }
169+}
170
171=== added file 'cmd/snappy/cmd_console_test.go'
172--- cmd/snappy/cmd_console_test.go 1970-01-01 00:00:00 +0000
173+++ cmd/snappy/cmd_console_test.go 2015-09-18 05:57:08 +0000
174@@ -0,0 +1,57 @@
175+// -*- Mode: Go; indent-tabs-mode: t -*-
176+
177+/*
178+ * Copyright (C) 2014-2015 Canonical Ltd
179+ *
180+ * This program is free software: you can redistribute it and/or modify
181+ * it under the terms of the GNU General Public License version 3 as
182+ * published by the Free Software Foundation.
183+ *
184+ * This program is distributed in the hope that it will be useful,
185+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
186+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
187+ * GNU General Public License for more details.
188+ *
189+ * You should have received a copy of the GNU General Public License
190+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
191+ *
192+ */
193+
194+package main
195+
196+import (
197+ "bytes"
198+
199+ . "gopkg.in/check.v1"
200+)
201+
202+func (s *CmdTestSuite) TestCmdConsoleCompleter(c *C) {
203+ // setup
204+ x := cmdConsole{}
205+
206+ err := x.initConsole()
207+ c.Assert(err, IsNil)
208+
209+ // from cmdline parser
210+ c.Check(x.snappyCompleter("hw-"), DeepEquals, []string{"hw-assign", "hw-info", "hw-unassign"})
211+
212+ // extra consoleCommand
213+ c.Check(x.snappyCompleter("he"), DeepEquals, []string{"help"})
214+ c.Check(x.snappyCompleter("help"), DeepEquals, []string{"help"})
215+}
216+
217+func (s *CmdTestSuite) TestDoHelpGeneric(c *C) {
218+ stdout = bytes.NewBuffer(nil)
219+
220+ x := cmdConsole{}
221+ x.doHelp("")
222+ c.Assert(stdout.(*bytes.Buffer).String(), Matches, `(?sm).*Available commands:`)
223+}
224+
225+func (s *CmdTestSuite) TestDoHelpSet(c *C) {
226+ stdout = bytes.NewBuffer(nil)
227+
228+ x := cmdConsole{}
229+ x.doHelp("set")
230+ c.Assert(stdout.(*bytes.Buffer).String(), Matches, `(?sm).*Set properties of system or package`)
231+}
232
233=== modified file 'debian/control'
234--- debian/control 2015-09-14 19:04:47 +0000
235+++ debian/control 2015-09-18 05:57:08 +0000
236@@ -15,6 +15,7 @@
237 golang-go-flags-dev,
238 golang-go.crypto-dev,
239 golang-goconfigparser-dev,
240+ golang-go-liner-dev,
241 golang-pb-dev,
242 golang-uboot-go-dev,
243 golang-yaml.v2-dev,
244
245=== modified file 'dependencies.tsv'
246--- dependencies.tsv 2015-09-16 12:04:05 +0000
247+++ dependencies.tsv 2015-09-18 05:57:08 +0000
248@@ -6,6 +6,7 @@
249 github.com/gosexy/gettext git 98b7b91596d20b96909e6b60d57411547dd9959c 2013-02-21T11:21:43Z
250 github.com/jessevdk/go-flags git 1acbbaff2f347c412a0c7884873bd72cc9c1f5b4 2015-08-16T10:05:21Z
251 github.com/mvo5/goconfigparser git 26426272dda20cc76aa1fa44286dc743d2972fe8 2015-02-12T09:37:50Z
252+github.com/peterh/liner git 1bb0d1c1a25ed393d8feb09bab039b2b1b1fbced 2015-04-02T04:04:07Z
253 github.com/mvo5/uboot-go git 361f6ebcbb54f389d15dc9faefa000e996ba3e37 2015-07-22T06:53:46Z
254 golang.org/x/crypto git 60052bd85f2d91293457e8811b0cf26b773de469 2015-06-22T23:34:07Z
255 gopkg.in/check.v1 git 64131543e7896d5bcc6bd5a76287eb75ea96c673 2014-10-24T13:38:53Z

Subscribers

People subscribed via source and target branches