Skip to content

Commit 58ec0b4

Browse files
authored
Merge pull request #166 from devlights/issue-#165
Add xdg examples
2 parents 0f6c838 + 922432a commit 58ec0b4

File tree

8 files changed

+221
-2
lines changed

8 files changed

+221
-2
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package xdgspec
2+
3+
import (
4+
"github.com/adrg/xdg"
5+
"github.com/devlights/try-golang/lib/output"
6+
"runtime"
7+
)
8+
9+
// XdgBaseDirectory は、XDG Base Directory についてのサンプルです.
10+
// [xdg](https://github.com/adrg/xdg) を利用して各値を取得しています.
11+
//
12+
// REFEFENCES::
13+
// - https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
14+
// - https://kledgeb.blogspot.com/2013/04/ubuntu-10-xdg-base-directory.html
15+
func XdgBaseDirectory() error {
16+
// ------------------------------------------------------------
17+
// XDG Base Directory について
18+
// XDG の各値は、xdg パッケージを利用すると簡単に利用できる
19+
// このパッケージは、Windows/MacOS/Unix に対応している
20+
//
21+
// xdg パッケージは、対象となる環境変数が設定されていれば、その値を返し
22+
// 設定されていない場合は、デフォルトの値を返すようになっている。
23+
// ------------------------------------------------------------
24+
output.Stdoutl("[OS]", runtime.GOOS)
25+
26+
// XDG_DATA_HOME
27+
// ユーザ個別のデータファイルが書き込まれる場所 (ユーザディレクトリ)
28+
output.Stdoutl("XDG_DATA_HOME", xdg.DataHome)
29+
30+
// XDG_CONFIG_HOME
31+
// ユーザ個別の設定が書き込まれる場所 (ユーザディレクトリ)
32+
output.Stdoutl("XDG_CONFIG_HOME", xdg.ConfigHome)
33+
34+
// XDG_CACHE_HOME
35+
// ユーザ毎のキャッシュデータの置き場 (ユーザディレクトリ)
36+
output.Stdoutl("XDG_CACHE_HOME", xdg.CacheHome)
37+
38+
// XDG_RUNTIME_DIR
39+
// ユーザ毎の実行時ファイルやその他のファイルを置くべき場所 (ユーザディレクトリ)
40+
output.Stdoutl("XDG_RUNTIME_DIR", xdg.RuntimeDir)
41+
42+
// XDG_DATA_DIRS
43+
// データファイルを検索する際のサーチパス (システムディレクトリ)
44+
//
45+
// (補足) アプリのデータを検索する場合は $XDG_DATA_HOME:$XDG_DATA_DIRS の順で行い
46+
// ユーザ毎のデータを優先させる
47+
output.Stdoutl("XDG_DATA_DIRS", xdg.DataDirs)
48+
49+
// XDG_CONFIG_DIRS
50+
// 設定ファイルを検索する際のサーチパス (システムディレクトリ)
51+
//
52+
// (補足) アプリの設定を検索する場合は $XDG_CONFIG_HOME:$XDG_CONFIG_DIRS の順で行い
53+
// ユーザ毎の設定を優先させる
54+
output.Stdoutl("XDG_CONFIG_DIRS", xdg.ConfigDirs)
55+
56+
return nil
57+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package xdgspec
2+
3+
import (
4+
"github.com/adrg/xdg"
5+
"github.com/devlights/try-golang/lib/output"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
9+
"runtime"
10+
)
11+
12+
// XdgFileOperation は、[xdg](https://github.com/adrg/xdg) を利用して
13+
// XDGの規定に従った場所にファイルを配置したり検索したりしています.
14+
func XdgFileOperation() error {
15+
var (
16+
dataDir = filepath.Join(xdg.DataHome, "try-golang")
17+
)
18+
19+
output.Stdoutl("[OS]", runtime.GOOS)
20+
output.Stdoutl("[dataDir]", dataDir)
21+
22+
// 処理する前に既にファイルが存在してたら消す
23+
if _, err := os.Stat(dataDir); err == nil {
24+
output.Stdoutl("[exists?]", "存在する --> 削除")
25+
26+
if err = os.RemoveAll(dataDir); err != nil {
27+
output.Stderrl("[os.Remove]", err)
28+
return err
29+
}
30+
} else {
31+
output.Stdoutl("[exists?]", "存在しない")
32+
}
33+
34+
// xdg.DataFile() に アプリ名/ファイル名 で渡すとXDGの規定に従ったパスを
35+
// 生成して返してくれる. xdg.DataFile() にすると $XDG_DATA_HOME
36+
// xdg.ConfigFile() にすると $XDG_CONFIG_HOME がベースとなる
37+
//
38+
// このとき、ファイルの親ディレクトリ(つまりアプリ名の部分)が
39+
// 存在しない場合は、ディレクトリを作成してくれる
40+
dataFile, err := xdg.DataFile("try-golang/mydata.txt")
41+
if err != nil {
42+
output.Stderrl("[xdg.DataFile]", err)
43+
return err
44+
}
45+
46+
output.Stdoutl("[xdg.DataFile]", dataFile)
47+
48+
if _, err = os.Stat(dataDir); err == nil {
49+
output.Stdoutl("[exists?]", "存在する")
50+
} else {
51+
output.Stdoutl("[exists?]", "存在しない")
52+
}
53+
54+
if err = ioutil.WriteFile(dataFile, []byte("helloworld\n"), 0644); err != nil {
55+
output.Stderrl("[ioutil.WriteFile]", err)
56+
return err
57+
}
58+
59+
if bytes, err := ioutil.ReadFile(dataFile); err == nil {
60+
output.Stdoutl("[ioutil.ReadFile]", string(bytes))
61+
}
62+
63+
// xdg.SearchDataFile() を利用すると、指定した アプリ名/ファイル名 を探してくれる.
64+
// 存在しない場合は、err に値が入る.
65+
// xdg.DataFile() と違い、こちらは親ディレクトリを作ったりはしてくれない.
66+
// 既にファイルが存在する場合に利用する.
67+
dataFile2, err := xdg.SearchDataFile("try-golang/mydata.txt")
68+
if err != nil {
69+
output.Stderrl("[xdg.SearchDataFile]", err)
70+
return err
71+
}
72+
73+
output.Stdoutl("[xdg.SearchDataFile]", dataFile2)
74+
75+
// 後始末
76+
_ = os.RemoveAll(dataDir)
77+
78+
return nil
79+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package xdgspec
2+
3+
import (
4+
"github.com/adrg/xdg"
5+
"github.com/devlights/try-golang/lib/output"
6+
"runtime"
7+
)
8+
9+
// XdgUserDirectory は、XDG User Directory についてのサンプルです.
10+
// [xdg](https://github.com/adrg/xdg) を利用して各値を取得しています.
11+
//
12+
// REFEFENCES::
13+
// - https://www.freedesktop.org/wiki/Software/xdg-user-dirs/
14+
func XdgUserDirectory() error {
15+
// ------------------------------------------------------------
16+
// XDG User Directory について
17+
// XDG の各値は、xdg パッケージを利用すると簡単に利用できる
18+
// このパッケージは、Windows/MacOS/Unix に対応している
19+
//
20+
// XDG User Directory は、Documents,Downloads,Music,Desktopなどの
21+
// $HOME に配置されるユーザ共通のディレクトリのセットのこと
22+
//
23+
// xdg パッケージは、対象となる環境変数が設定されていれば、その値を返し
24+
// 設定されていない場合は、デフォルトの値を返すようになっている。
25+
// ------------------------------------------------------------
26+
output.Stdoutl("[OS]", runtime.GOOS)
27+
28+
// XDG_DESKTOP_DIR
29+
// デスクトップの場所
30+
output.Stdoutl("XDG_DESKTOP_DIR", xdg.UserDirs.Desktop)
31+
32+
// XDG_DOWNLOAD_DIR
33+
// ダウンロードの場所
34+
output.Stdoutl("XDG_DOWNLOAD_DIR", xdg.UserDirs.Download)
35+
36+
// XDG_DOCUMENTS_DIR
37+
// ドキュメントの場所
38+
output.Stdoutl("XDG_DOCUMENTS_DIR", xdg.UserDirs.Documents)
39+
40+
// XDGの標準規定にはないもの
41+
output.Stdoutl("Application dirs", xdg.ApplicationDirs)
42+
output.Stdoutl("Font dirs", xdg.FontDirs)
43+
44+
return nil
45+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/devlights/try-golang
33
go 1.13
44

55
require (
6+
github.com/adrg/xdg v0.2.1
67
github.com/cheekybits/genny v1.0.0
78
github.com/deckarep/golang-set v1.7.1
89
github.com/getsentry/sentry-go v0.4.0

go.sum

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mo
55
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
66
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
77
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
8+
github.com/adrg/xdg v0.2.1 h1:VSVdnH7cQ7V+B33qSJHTCRlNgra1607Q8PzEmnvb2Ic=
9+
github.com/adrg/xdg v0.2.1/go.mod h1:ZuOshBmzV4Ta+s23hdfFZnBsdzmoR3US0d7ErpqSbTQ=
810
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
911
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
1012
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
@@ -16,6 +18,7 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
1618
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
1719
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
1820
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
21+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1922
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2023
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
2124
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
@@ -101,6 +104,7 @@ github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4
101104
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
102105
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
103106
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
107+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
104108
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
105109
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
106110
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
@@ -117,6 +121,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
117121
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
118122
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
119123
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
124+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
120125
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
121126
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
122127
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
@@ -159,11 +164,13 @@ golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGm
159164
golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
160165
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
161166
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
167+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
162168
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
163169
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
164170
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
165171
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
166172
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
167173
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
168174
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
175+
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
169176
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

lib/mapping.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/devlights/try-golang/advanced/generate"
77
"github.com/devlights/try-golang/advanced/reflection"
88
"github.com/devlights/try-golang/advanced/sets"
9+
"github.com/devlights/try-golang/advanced/xdgspec"
910
"github.com/devlights/try-golang/basic/array_"
1011
"github.com/devlights/try-golang/basic/builtin_"
1112
"github.com/devlights/try-golang/basic/comments"
@@ -143,6 +144,9 @@ func (m SampleMapping) MakeMapping() {
143144
m["sort_interface"] = sort_.SortInterface
144145
m["generate_generic_stack"] = generate.UseGenericStack
145146
m["generate_generic_queue"] = generate.UseGenericQueue
147+
m["xdg_base_directory"] = xdgspec.XdgBaseDirectory
148+
m["xdg_user_directory"] = xdgspec.XdgUserDirectory
149+
m["xdg_file_operation"] = xdgspec.XdgFileOperation
146150

147151
m["tutorial_gotour_helloworld"] = tutorial.HelloWorld
148152
m["tutorial_gotour_import"] = tutorial.Import

lib/output/output.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ var (
1313
defaultErrWriter io.Writer = os.Stderr
1414
)
1515

16+
// prefix の align についての値. デフォルトは left-align
17+
var (
18+
defaultPrefixAlignFormat = "%-20s"
19+
prefixAlignFormat = "%s"
20+
)
21+
22+
func init() {
23+
SetPrefixFormat(defaultPrefixAlignFormat)
24+
}
25+
26+
// PrefixFormat は、現在の prefix の フォーマットを返します
27+
func PrefixFormat() string {
28+
return prefixAlignFormat
29+
}
30+
31+
// SetPrefixFormat は、指定した値を prefix のフォーマットとして設定します.
32+
func SetPrefixFormat(f string) {
33+
prefixAlignFormat = f
34+
}
35+
1636
// Writer は、現在設定されている標準出力用のio.Writerを返します.
1737
func Writer() io.Writer {
1838
return defaultWriter
@@ -56,7 +76,8 @@ func Stderrf(prefix string, format string, values ...interface{}) {
5676
func _pf(w io.Writer, prefix string, format string, values ...interface{}) {
5777
if prefix != "" {
5878
s := fmt.Sprintf(format, values...)
59-
_, _ = fmt.Fprintf(w, "%s %s", prefix, s)
79+
p := fmt.Sprintf(PrefixFormat(), prefix)
80+
_, _ = fmt.Fprintf(w, "%s %s", p, s)
6081
} else {
6182
_, _ = fmt.Fprintf(w, format, values...)
6283
}
@@ -65,7 +86,8 @@ func _pf(w io.Writer, prefix string, format string, values ...interface{}) {
6586
func _pl(w io.Writer, prefix string, values ...interface{}) {
6687
if prefix != "" {
6788
s := fmt.Sprintln(values...)
68-
_, _ = fmt.Fprint(w, prefix, " ", s)
89+
p := fmt.Sprintf(PrefixFormat(), prefix)
90+
_, _ = fmt.Fprint(w, p, " ", s)
6991
} else {
7092
_, _ = fmt.Fprintln(w, values...)
7193
}

lib/output/output_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import (
77
"testing"
88
)
99

10+
func init() {
11+
SetPrefixFormat("%s")
12+
}
13+
1014
func TestStdoutl(t *testing.T) {
1115
// Arrange
1216
var (

0 commit comments

Comments
 (0)