Skip to content

Commit a941b3b

Browse files
committed
WIP: better handling of cache conflict results
1 parent 6764e5c commit a941b3b

File tree

2 files changed

+79
-16
lines changed

2 files changed

+79
-16
lines changed

api/api.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"net/url"
1414
"os"
1515
"strings"
16+
"text/tabwriter"
1617
"text/template"
1718

1819
log "github.com/Sirupsen/logrus"
@@ -913,7 +914,7 @@ func (s *ScalewayAPI) PutVolume(volumeID string, definition ScalewayVolumePutDef
913914
}
914915

915916
// ResolveServer attempts the find a matching Identifier for the input string
916-
func (s *ScalewayAPI) ResolveServer(needle string) ([]string, error) {
917+
func (s *ScalewayAPI) ResolveServer(needle string) ([]ScalewayResolverResult, error) {
917918
servers := s.Cache.LookUpServers(needle, true)
918919
if len(servers) == 0 {
919920
_, err := s.GetServers(true, 0)
@@ -1184,20 +1185,28 @@ func (s *ScalewayAPI) GetServerID(needle string) string {
11841185
log.Fatalf("Unable to resolve server %s: %s", needle, err)
11851186
}
11861187
if len(servers) == 1 {
1187-
return servers[0]
1188+
return servers[0].Identifier
11881189
}
11891190
if len(servers) == 0 {
11901191
log.Fatalf("No such server: %s", needle)
11911192
}
1192-
log.Errorf("Too many candidates for %s (%d)", needle, len(servers))
1193-
for _, identifier := range servers {
1194-
// FIXME: also print the name
1195-
log.Infof("- %s", identifier)
1196-
}
1193+
1194+
showResolverResults(needle, servers)
11971195
os.Exit(1)
11981196
return ""
11991197
}
12001198

1199+
func showResolverResults(needle string, results []ScalewayResolverResult) error {
1200+
log.Errorf("Too many candidates for %s (%d)", needle, len(results))
1201+
1202+
w := tabwriter.NewWriter(os.Stderr, 20, 1, 3, ' ', 0)
1203+
defer w.Flush()
1204+
for _, result := range results {
1205+
fmt.Fprintf(w, "- %s\t%s\t%s\n", result.TruncIdentifier(), result.CodeName(), result.Name)
1206+
}
1207+
return nil
1208+
}
1209+
12011210
// GetSnapshotID returns exactly one snapshot matching or dies
12021211
func (s *ScalewayAPI) GetSnapshotID(needle string) string {
12031212
// Parses optional type prefix, i.e: "snapshot:name" -> "name"

api/cache.go

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package api
66

77
import (
88
"encoding/json"
9+
"fmt"
910
"io/ioutil"
1011
"os"
1112
"path/filepath"
@@ -69,6 +70,27 @@ type ScalewayIdentifier struct {
6970
Type int
7071
}
7172

73+
// ScalewayResolverResult is a structure containing human-readable information
74+
// about resolver results. This structure is used to display the user choices.
75+
type ScalewayResolverResult struct {
76+
Identifier string
77+
Type string
78+
Name string
79+
}
80+
81+
func (s *ScalewayResolverResult) TruncIdentifier() string {
82+
return s.Identifier[:8]
83+
}
84+
85+
func (s *ScalewayResolverResult) CodeName() string {
86+
name := strings.ToLower(s.Name)
87+
name = regexp.MustCompile(`[^a-z0-9-]`).ReplaceAllString(name, "-")
88+
name = regexp.MustCompile(`--+`).ReplaceAllString(name, "-")
89+
name = strings.Trim(name, "-")
90+
91+
return fmt.Sprintf("%s:%s", strings.ToLower(s.Type), name)
92+
}
93+
7294
// NewScalewayCache loads a per-user cache
7395
func NewScalewayCache() (*ScalewayCache, error) {
7496
homeDir := os.Getenv("HOME") // *nix
@@ -260,32 +282,64 @@ func (c *ScalewayCache) LookUpBootscripts(needle string, acceptUUID bool) []stri
260282
}
261283

262284
// LookUpServers attempts to return identifiers matching a pattern
263-
func (c *ScalewayCache) LookUpServers(needle string, acceptUUID bool) []string {
285+
func (c *ScalewayCache) LookUpServers(needle string, acceptUUID bool) []ScalewayResolverResult {
264286
c.Lock.Lock()
265287
defer c.Lock.Unlock()
266288

267-
var res []string
268-
var exactMatches []string
289+
var res []ScalewayResolverResult
290+
var exactMatches []ScalewayResolverResult
269291

270292
if acceptUUID && uuid.Parse(needle) != nil {
271-
res = append(res, needle)
293+
entry := ScalewayResolverResult{
294+
Identifier: needle,
295+
Name: needle,
296+
Type: "Server",
297+
}
298+
res = append(res, entry)
272299
}
273300

274301
nameRegex := regexp.MustCompile(`(?i)` + regexp.MustCompile(`[_-]`).ReplaceAllString(needle, ".*"))
275302
for identifier, name := range c.Servers {
276303
if name == needle {
277-
exactMatches = append(exactMatches, identifier)
304+
entry := ScalewayResolverResult{
305+
Identifier: identifier,
306+
Name: name,
307+
Type: "Server",
308+
}
309+
exactMatches = append(exactMatches, entry)
278310
}
279311
if strings.HasPrefix(identifier, needle) || nameRegex.MatchString(name) {
280-
res = append(res, identifier)
312+
entry := ScalewayResolverResult{
313+
Identifier: identifier,
314+
Name: name,
315+
Type: "Server",
316+
}
317+
res = append(res, entry)
281318
}
282319
}
283320

284321
if len(exactMatches) == 1 {
285322
return exactMatches
286323
}
287324

288-
return utils.RemoveDuplicates(res)
325+
return removeDuplicatesResults(res)
326+
}
327+
328+
// removeDuplicatesResults transforms an array into a unique array
329+
func removeDuplicatesResults(elements []ScalewayResolverResult) []ScalewayResolverResult {
330+
encountered := map[string]ScalewayResolverResult{}
331+
332+
// Create a map of all unique elements.
333+
for v := range elements {
334+
encountered[elements[v].Identifier] = elements[v]
335+
}
336+
337+
// Place all keys from the map into a slice.
338+
results := []ScalewayResolverResult{}
339+
for _, result := range encountered {
340+
results = append(results, result)
341+
}
342+
return results
289343
}
290344

291345
// parseNeedle parses a user needle and try to extract a forced object type
@@ -319,9 +373,9 @@ func (c *ScalewayCache) LookUpIdentifiers(needle string) []ScalewayIdentifier {
319373
identifierType, needle := parseNeedle(needle)
320374

321375
if identifierType&(IdentifierUnknown|IdentifierServer) > 0 {
322-
for _, identifier := range c.LookUpServers(needle, false) {
376+
for _, result := range c.LookUpServers(needle, false) {
323377
results = append(results, ScalewayIdentifier{
324-
Identifier: identifier,
378+
Identifier: result.Identifier,
325379
Type: IdentifierServer,
326380
})
327381
}

0 commit comments

Comments
 (0)