Skip to content

Commit 1b389b1

Browse files
committed
feat: follow XDG Base Directory Specification
1 parent 4ece259 commit 1b389b1

File tree

12 files changed

+60
-63
lines changed

12 files changed

+60
-63
lines changed

cmd/init.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ import (
1717
"encoding/gob"
1818
"fmt"
1919
"os"
20-
"path"
2120

2221
vt "github.com/VirusTotal/vt-go"
23-
"github.com/mitchellh/go-homedir"
22+
"github.com/adrg/xdg"
2423
"github.com/spf13/cobra"
2524
)
2625

@@ -51,7 +50,7 @@ func NewInitCmd() *cobra.Command {
5150

5251
Run: func(cmd *cobra.Command, args []string) {
5352

54-
fmt.Printf(vtBanner)
53+
fmt.Print(vtBanner)
5554

5655
apiKey := cmd.Flags().Lookup("apikey").Value.String()
5756

@@ -68,13 +67,13 @@ func NewInitCmd() *cobra.Command {
6867
os.Exit(1)
6968
}
7069

71-
dir, err := homedir.Dir()
70+
relCache, err := xdg.CacheFile("vt-cli/relationships")
7271
if err != nil {
7372
fmt.Fprintln(os.Stderr, err)
7473
os.Exit(1)
7574
}
7675

77-
relCacheFile, err := os.Create(path.Join(dir, ".vt.relationships.cache"))
76+
relCacheFile, err := os.Create(relCache)
7877
if err != nil {
7978
fmt.Fprintln(os.Stderr, err)
8079
os.Exit(1)
@@ -88,7 +87,12 @@ func NewInitCmd() *cobra.Command {
8887
os.Exit(1)
8988
}
9089

91-
configFilePath := path.Join(dir, ".vt.toml")
90+
configFilePath, err := xdg.ConfigFile("vt-cli/vt.toml")
91+
if err != nil {
92+
fmt.Fprintln(os.Stderr, err)
93+
os.Exit(1)
94+
}
95+
9296
configFile, err := os.Create(configFilePath)
9397
if err != nil {
9498
fmt.Fprintln(os.Stderr, err)

cmd/privileges.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
func NewPrivilegeCmd(target string) *cobra.Command {
1313
cmd := &cobra.Command{
14-
Use: "privileges",
14+
Use: "privileges",
1515
Short: fmt.Sprintf("Change %s privileges", target),
1616
}
1717

@@ -21,23 +21,22 @@ func NewPrivilegeCmd(target string) *cobra.Command {
2121
return cmd
2222
}
2323

24-
2524
type Privilege struct {
26-
Granted bool `json:"granted"`
25+
Granted bool `json:"granted"`
2726
ExpirationDate int64 `json:"expiration_date"`
2827
}
2928

3029
type Privileges map[string]Privilege
3130

3231
func NewPrivilegeGrantCmd(target string) *cobra.Command {
3332
cmd := &cobra.Command{
34-
Use: fmt.Sprintf("grant [%sname] [privilege]...", target),
35-
Short: fmt.Sprintf("Grant privileges to a %s", target),
33+
Use: fmt.Sprintf("grant [%sname] [privilege]...", target),
34+
Short: fmt.Sprintf("Grant privileges to a %s", target),
3635
Example: fmt.Sprintf(" vt %s privileges grant my%s intelligence downloads-tier-2", target, target),
37-
Args: cobra.MinimumNArgs(2),
36+
Args: cobra.MinimumNArgs(2),
3837
RunE: func(cmd *cobra.Command, args []string) error {
3938
var expirationDate int64
40-
if expiration:= viper.GetString("expiration"); expiration != "" {
39+
if expiration := viper.GetString("expiration"); expiration != "" {
4140
var err error
4241
expirationDate, err = strconv.ParseInt(expiration, 10, 64)
4342
if err != nil {
@@ -68,18 +67,18 @@ func NewPrivilegeGrantCmd(target string) *cobra.Command {
6867
},
6968
}
7069

71-
cmd.Flags().StringP("" +
70+
cmd.Flags().StringP(""+
7271
"expiration", "e", "",
7372
"expiration time for the granted privileges (UNIX timestamp or YYYY-MM-DD)")
7473
return cmd
7574
}
7675

7776
func NewPrivilegeRevokeCmd(target string) *cobra.Command {
7877
return &cobra.Command{
79-
Use: fmt.Sprintf("revoke [%sname] [privilege]...", target),
80-
Short: fmt.Sprintf("Revoke privileges from a %s", target),
78+
Use: fmt.Sprintf("revoke [%sname] [privilege]...", target),
79+
Short: fmt.Sprintf("Revoke privileges from a %s", target),
8180
Example: fmt.Sprintf(" vt %s privileges revoke my%s intelligence downloads-tier-2", target, target),
82-
Args: cobra.MinimumNArgs(2),
81+
Args: cobra.MinimumNArgs(2),
8382
RunE: func(cmd *cobra.Command, args []string) error {
8483
privileges := Privileges{}
8584
for _, arg := range args[1:] {

cmd/relationship.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,23 @@ import (
1919
"fmt"
2020
"github.com/VirusTotal/vt-cli/utils"
2121
"os"
22-
"path"
2322
"sync"
2423

2524
vt "github.com/VirusTotal/vt-go"
26-
homedir "github.com/mitchellh/go-homedir"
25+
"github.com/adrg/xdg"
2726
"github.com/spf13/cobra"
2827
"github.com/spf13/viper"
2928
)
3029

3130
var objectRelationshipsMap map[string][]vt.RelationshipMeta
3231

3332
func init() {
34-
home, _ := homedir.Dir()
35-
f, err := os.Open(path.Join(home, ".vt.relationships.cache"))
33+
cachePath, err := xdg.SearchCacheFile("vt-cli/relationships")
34+
if err != nil {
35+
return
36+
}
37+
38+
f, err := os.Open(cachePath)
3639
if err == nil {
3740
defer f.Close()
3841
dec := gob.NewDecoder(f)

cmd/url.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ var urlCmdExample = ` vt url https://www.virustotal.com
3535
vt url f1177df4692356280844e1d5af67cc4a9eccecf77aa61c229d483b7082c70a8e
3636
cat list_of_urls | vt url -`
3737

38-
3938
// Regular expressions used for validating a URL identifier.
4039
var urlID = regexp.MustCompile(`[0-9a-fA-F]{64}`)
4140

@@ -55,7 +54,7 @@ func NewURLCmd() *cobra.Command {
5554
}
5655
r := utils.NewMappedStringReader(
5756
utils.StringReaderFromCmdArgs(args),
58-
func (url string) string {
57+
func(url string) string {
5958
if urlID.MatchString(url) {
6059
// The user provided a URL identifier as returned by
6160
// VirusTotal's API, which consists in the URL's SHA-256.

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ go 1.22.0
44

55
require (
66
github.com/VirusTotal/vt-go v1.0.1
7+
github.com/adrg/xdg v0.5.3
78
github.com/briandowns/spinner v1.23.1
89
github.com/cavaliergopher/grab/v3 v3.0.1
910
github.com/dustin/go-humanize v1.0.1
1011
github.com/fatih/color v1.17.0
1112
github.com/gobwas/glob v0.2.3
1213
github.com/gosuri/uitable v0.0.4
1314
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213
14-
github.com/mitchellh/go-homedir v1.1.0
1515
github.com/plusvic/go-ansi v0.0.0-20180516115420-9879244c4340
1616
github.com/spf13/cobra v1.8.1
1717
github.com/spf13/pflag v1.0.5
@@ -45,7 +45,7 @@ require (
4545
go.uber.org/atomic v1.9.0 // indirect
4646
go.uber.org/multierr v1.9.0 // indirect
4747
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
48-
golang.org/x/sys v0.18.0 // indirect
48+
golang.org/x/sys v0.26.0 // indirect
4949
golang.org/x/term v0.1.0 // indirect
5050
golang.org/x/text v0.14.0 // indirect
5151
gopkg.in/ini.v1 v1.67.0 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
github.com/VirusTotal/vt-go v1.0.1 h1:rj/qugIY8XNC6ogwOaeJAGCOsb3nmY63+yuDMtHOx0Q=
22
github.com/VirusTotal/vt-go v1.0.1/go.mod h1:u1+HeRyl/gQs67eDgVEWNE7+x+zCyXhdtNVrRJR5YPE=
3+
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
4+
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
35
github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650=
46
github.com/briandowns/spinner v1.23.1/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM=
57
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
@@ -43,8 +45,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
4345
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
4446
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
4547
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
46-
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
47-
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
4848
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
4949
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
5050
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
@@ -101,8 +101,8 @@ golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
101101
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
102102
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
103103
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
104-
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
105-
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
104+
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
105+
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
106106
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
107107
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
108108
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=

utils/filter.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,18 @@ import (
2525
// excluding keys matching any of the patterns in "exclude". The logic for
2626
// determining if a key matches the pattern goes as follow:
2727
//
28-
// * The path for the key is computed. If the key is in the top-level map its
29-
// path is the key itself, if the key is contained within a nested map its
30-
// path is the concatenation of the parent's path and the key, using a dot (.)
31-
// as a separator. The path for "key" in {a:{b:{key:val}}} is a.b.key.
28+
// - The path for the key is computed. If the key is in the top-level map its
29+
// path is the key itself, if the key is contained within a nested map its
30+
// path is the concatenation of the parent's path and the key, using a dot (.)
31+
// as a separator. The path for "key" in {a:{b:{key:val}}} is a.b.key.
3232
//
33-
// * The path is matched against the pattern, which can contain asterisks (*)
34-
// as a placeholder for any character different from a dot (.) and ** as a
35-
// placeholder for any character including a dot. For more information go to:
36-
// https://godoc.org/github.com/gobwas/glob#Compile
37-
//
38-
// * If the path matches any pattern in "include" the key is included in the
39-
// resulting map, as long as it doesn't match a pattern in "exclude".
33+
// - The path is matched against the pattern, which can contain asterisks (*)
34+
// as a placeholder for any character different from a dot (.) and ** as a
35+
// placeholder for any character including a dot. For more information go to:
36+
// https://godoc.org/github.com/gobwas/glob#Compile
4037
//
38+
// - If the path matches any pattern in "include" the key is included in the
39+
// resulting map, as long as it doesn't match a pattern in "exclude".
4140
func FilterMap(m map[string]interface{}, include, exclude []string) map[string]interface{} {
4241
includeGlob := make([]glob.Glob, len(include))
4342
excludeGlob := make([]glob.Glob, len(exclude))

utils/filter_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// you may not use this file except in compliance with the License.
44
// You may obtain a copy of the License at
55
//
6-
// http://www.apache.org/licenses/LICENSE-2.0
6+
// http://www.apache.org/licenses/LICENSE-2.0
77
//
88
// Unless required by applicable law or agreed to in writing, software
99
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -77,9 +77,7 @@ var testCases = []testCase{
7777
include: []string{"foo"},
7878
exclude: []string{"**.quux"},
7979
input: testMap,
80-
output: map[string]interface{}{
81-
82-
},
80+
output: map[string]interface{}{},
8381
},
8482

8583
testCase{

utils/pqueue_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// you may not use this file except in compliance with the License.
44
// You may obtain a copy of the License at
55
//
6-
// http://www.apache.org/licenses/LICENSE-2.0
6+
// http://www.apache.org/licenses/LICENSE-2.0
77
//
88
// Unless required by applicable law or agreed to in writing, software
99
// distributed under the License is distributed on an "AS IS" BASIS,

vt/main.go

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,25 @@
1414
package main
1515

1616
import (
17-
"fmt"
1817
"os"
18+
"path"
1919

2020
"github.com/VirusTotal/vt-cli/cmd"
21-
homedir "github.com/mitchellh/go-homedir"
21+
"github.com/adrg/xdg"
2222
"github.com/spf13/cobra"
2323
"github.com/spf13/viper"
2424
)
2525

2626
// initConfig reads in config file and ENV variables if set.
2727
func initConfig() {
2828

29-
// Find home directory.
30-
home, err := homedir.Dir()
31-
if err != nil {
32-
fmt.Fprintln(os.Stderr, err)
33-
os.Exit(1)
29+
// Search config in XDG config directory and current directory
30+
for _, v := range xdg.ConfigDirs {
31+
viper.AddConfigPath(path.Join(v, "vt-cli"))
3432
}
35-
36-
// Search config in home directory and current directory
37-
viper.AddConfigPath(home)
3833
viper.AddConfigPath(".")
39-
// Config file must be named .vt + format extension (.toml, .json, etc)
40-
viper.SetConfigName(".vt")
34+
// Config file must be named vt + format extension (.toml, .json, etc)
35+
viper.SetConfigName("vt")
4136

4237
// The prefix for all environment variables will be VTCLI_. Examples:
4338
// VTCLI_PROXY, VTCLI_APIKEY.

0 commit comments

Comments
 (0)