├── .github ├── PULL_REQUEST_TEMPLATE.md ├── CONTRIBUTING.md └── FUNDING.yml ├── speak ├── media ├── sadako.mp3 └── sadako.png ├── Makefile ├── main.go ├── .gitignore ├── cmd └── speak.go ├── sound └── speak.go ├── menu └── cli.go ├── Gopkg.toml ├── art └── aa.go ├── LICENSE ├── README.md ├── Gopkg.lock └── action └── cli.go /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # TL;DR 2 | 3 | - fix typo. -------------------------------------------------------------------------------- /speak: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konojunya/sadako/HEAD/speak -------------------------------------------------------------------------------- /media/sadako.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konojunya/sadako/HEAD/media/sadako.mp3 -------------------------------------------------------------------------------- /media/sadako.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/konojunya/sadako/HEAD/media/sadako.png -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | go build -o speak cmd/speak.go 3 | 4 | install: 5 | go build -o sadako main.go 6 | chmod u+x sadako -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/konojunya/sadako/menu" 7 | ) 8 | 9 | func main() { 10 | app := menu.Getapp() 11 | app.Run(os.Args) 12 | } 13 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contribution 2 | 3 | Please check the [issue](https://github.com/konojunya/sadako/issues). 4 | 5 | 1. Fork it (https://github.com/konojunya/sadako) 6 | 2. Create your feature branch 7 | 3. Commit your changes 8 | 4. Push to the branch 9 | 5. Create new Pull Request! :) -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | 16 | vendor/ 17 | sadako 18 | -------------------------------------------------------------------------------- /cmd/speak.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/konojunya/sadako/art" 7 | "github.com/konojunya/sadako/sound" 8 | ) 9 | 10 | func main() { 11 | f, err := os.Open(os.Getenv("GOPATH") + "/src/github.com/konojunya/sadako/media/sadako.mp3") 12 | if err != nil { 13 | panic(err) 14 | } 15 | 16 | art.DrawAA() 17 | if err = sound.Speak(f); err != nil { 18 | panic(err) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: konojunya # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /sound/speak.go: -------------------------------------------------------------------------------- 1 | package sound 2 | 3 | import ( 4 | "os" 5 | "time" 6 | 7 | "github.com/faiface/beep" 8 | "github.com/faiface/beep/mp3" 9 | "github.com/faiface/beep/speaker" 10 | ) 11 | 12 | // Speak Play Sadako's sound 13 | func Speak(f *os.File) error { 14 | s, format, err := mp3.Decode(f) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | done := make(chan struct{}) 20 | err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) 21 | if err != nil { 22 | return err 23 | } 24 | speaker.Play(beep.Seq(s, beep.Callback(func() { 25 | close(done) 26 | }))) 27 | _ = <-done 28 | 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /menu/cli.go: -------------------------------------------------------------------------------- 1 | package menu 2 | 3 | import ( 4 | "github.com/konojunya/sadako/action" 5 | "github.com/urfave/cli" 6 | ) 7 | 8 | // Getapp Returning the app that finished setting to main.go 9 | func Getapp() *cli.App { 10 | app := cli.NewApp() 11 | config(app) 12 | app.Commands = getCommands() 13 | return app 14 | } 15 | 16 | func config(app *cli.App) { 17 | app.Name = "sadako" 18 | app.Usage = "Sadako will appear when git pull" 19 | app.Version = "1.0.0" 20 | } 21 | 22 | func getCommands() []cli.Command { 23 | return []cli.Command{ 24 | { 25 | Name: "init", 26 | Usage: "sadako in your git repository", 27 | Action: action.Set, 28 | }, 29 | { 30 | Name: "rm", 31 | Usage: "remove sadako... :)", 32 | Action: action.Remove, 33 | }, 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [prune] 29 | go-tests = true 30 | unused-packages = true 31 | -------------------------------------------------------------------------------- /art/aa.go: -------------------------------------------------------------------------------- 1 | package art 2 | 3 | import ( 4 | "bytes" 5 | "compress/gzip" 6 | "encoding/base64" 7 | "fmt" 8 | "io" 9 | ) 10 | 11 | var aa = "" + 12 | "H4sIAGdplloAA3u/Z/97IhBXzeOGBgVcsvHxINkasKIaKwwAFiZWUkH//f7FEJTwqGfS+z170MxW" + 13 | "gDhlXycQPd0+93Hz3vgiWxu4KRCtYDVAWQgCCe+bBVISHw9UBZIHYoUnO/ZDlb3YNA9IgsTe75sB" + 14 | "RBDTgD4DmaMPxOjGgRSApLmgcvrggOiHK+ECC2LTzAVUBhTwAglC5CDiQFu5oD6CyCBkQVJcAE4i" + 15 | "5FepAQAA" 16 | 17 | // DrawAA Draw Sadako's AA 18 | func DrawAA() { 19 | 20 | b, err := base64.StdEncoding.DecodeString(aa) 21 | if err != nil { 22 | panic(err) 23 | } 24 | r, err := gzip.NewReader(bytes.NewReader(b)) 25 | if err != nil { 26 | panic(err) 27 | } 28 | var buf bytes.Buffer 29 | if _, err = io.Copy(&buf, r); err != nil { 30 | panic(err) 31 | } 32 | fmt.Println(buf.String()) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Junya Kono 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sadako 2 | 3 | Sadako will appear after merge :) 4 | 5 | ![](https://raw.githubusercontent.com/konojunya/sadako/master/media/sadako.png) 6 | 7 | ## Description 8 | 9 | Sadako is a command line tool that hooks the git-pull event (post-merge) and plays a parody of a famous song. 10 | 11 | Since Sadako's explanation is at the bottom of the README, I think that it is better for those who do not know Sadako to go through it once. 12 | 13 | ## Installation 14 | 15 | ``` 16 | $ go get github.com/konojunya/sadako 17 | ``` 18 | 19 | ## Usage 20 | 21 | - I will send Sadako to your git repository. 22 | 23 | 24 | ``` 25 | $ sadako init 26 | ``` 27 | 28 | - Remove Sadako from git repository. 29 | 30 | ``` 31 | $ sadako rm 32 | ``` 33 | 34 | ## Development 35 | 36 | ``` 37 | $ dep ensure 38 | $ make build 39 | $ make install 40 | ``` 41 | 42 | ## Who is Sadako? 43 | 44 | > Sadako is a fictitious character who appears in a Japanese movie called a 'Ring'. 45 | > Leave unrefined or grudge in this world, trigger a disaster starting from the "curse video" that curses and kills those who saw. 46 | 47 | ## Contribution 48 | 49 | Please check the [issue](https://github.com/konojunya/sadako/issues). 50 | 51 | 1. Fork it https://github.com/konojunya/sadako 52 | 2. Create your feature branch 53 | 3. Commit your changes 54 | 4. Push to the branch 55 | 5. Create new Pull Request! :) 56 | 57 | ## Licence 58 | 59 | [MIT](https://github.com/tcnksm/tool/blob/master/LICENCE) 60 | 61 | ## Collaborator 62 | 63 | - [@kinokoruumu](https://github.com/kinokoruumu) 64 | - [@mattn](https://github.com/mattn) 65 | 66 | 67 | ## Auther 68 | 69 | [@konojunya](https://twitter.com/konojunya) 70 | -------------------------------------------------------------------------------- /Gopkg.lock: -------------------------------------------------------------------------------- 1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. 2 | 3 | 4 | [[projects]] 5 | branch = "master" 6 | name = "github.com/faiface/beep" 7 | packages = [ 8 | ".", 9 | "mp3", 10 | "speaker" 11 | ] 12 | revision = "cc52b09e4638e22175c50013413fde5fac224e97" 13 | 14 | [[projects]] 15 | branch = "master" 16 | name = "github.com/gopherjs/gopherjs" 17 | packages = ["js"] 18 | revision = "df18d38287ab2ed3138d564e7c8cbe4d5a249d87" 19 | 20 | [[projects]] 21 | branch = "master" 22 | name = "github.com/hajimehoshi/go-mp3" 23 | packages = [ 24 | ".", 25 | "internal/bits", 26 | "internal/consts", 27 | "internal/frame", 28 | "internal/frameheader", 29 | "internal/huffman", 30 | "internal/imdct", 31 | "internal/maindata", 32 | "internal/sideinfo" 33 | ] 34 | revision = "3c185f92b8dbceefa913b64cae634ba47f452769" 35 | 36 | [[projects]] 37 | branch = "master" 38 | name = "github.com/hajimehoshi/oto" 39 | packages = [ 40 | ".", 41 | "internal/jni" 42 | ] 43 | revision = "e2f7012830c68205e59a6663c6e2398f6f778629" 44 | 45 | [[projects]] 46 | name = "github.com/pkg/errors" 47 | packages = ["."] 48 | revision = "645ef00459ed84a119197bfb8d8205042c6df63d" 49 | version = "v0.8.0" 50 | 51 | [[projects]] 52 | name = "github.com/urfave/cli" 53 | packages = ["."] 54 | revision = "cfb38830724cc34fedffe9a2a29fb54fa9169cd1" 55 | version = "v1.20.0" 56 | 57 | [solve-meta] 58 | analyzer-name = "dep" 59 | analyzer-version = 1 60 | inputs-digest = "870cd3f5206182d745b06d71b245b20b5b71efe0dad790da9f7eaf90dbd727b7" 61 | solver-name = "gps-cdcl" 62 | solver-version = 1 63 | -------------------------------------------------------------------------------- /action/cli.go: -------------------------------------------------------------------------------- 1 | package action 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "os" 7 | 8 | "github.com/urfave/cli" 9 | ) 10 | 11 | // Remove sadakoを実行したrepositoryから削除する 12 | func Remove(c *cli.Context) { 13 | // When not git repository. 14 | found := exists(".git") 15 | if !found { 16 | fmt.Println("This directory is not git repository yet :(") 17 | os.Exit(1) 18 | } 19 | 20 | var sadako = ".git/hooks/post-merge" 21 | sadakoFound := exists(sadako) 22 | if !sadakoFound { 23 | fmt.Println("sadako speak binary is not found.\n" + 24 | "Where did she go... :p") 25 | os.Exit(1) 26 | } 27 | if err := os.Remove(sadako); err != nil { 28 | panic(err) 29 | } 30 | 31 | fmt.Println("Sadako has gone :)") 32 | 33 | } 34 | 35 | // Set copy to .git/hooks/post-merge 36 | func Set(c *cli.Context) { 37 | sadakoSrcPath := os.Getenv("GOPATH") + "/src/github.com/konojunya/sadako" 38 | 39 | // When not git repository. 40 | found := exists(".git") 41 | if !found { 42 | fmt.Println("This directory is not git repository yet :(") 43 | os.Exit(1) 44 | } 45 | 46 | // When not found source. 47 | found = exists(sadakoSrcPath) 48 | if !found { 49 | fmt.Println("sadako speak binary is not found.\n" + 50 | "Please `go get github.com/konojunya/sadako`") 51 | os.Exit(1) 52 | } 53 | 54 | // first: sadako-speak 55 | path, err := os.Getwd() 56 | if err != nil { 57 | panic(err) 58 | } 59 | 60 | if err = copy(sadakoSrcPath+"/speak", path+"/.git/hooks/post-merge"); err != nil { 61 | panic(err) 62 | } 63 | // Grant execution authority 64 | os.Chmod(path+"/.git/hooks/post-merge", 0755) 65 | 66 | fmt.Println("Sadako is near you... :)") 67 | } 68 | 69 | func copy(srcpath, distpath string) error { 70 | src, err := os.Open(srcpath) 71 | if err != nil { 72 | return err 73 | } 74 | defer src.Close() 75 | 76 | dist, err := os.Create(distpath) 77 | if err != nil { 78 | return err 79 | } 80 | defer dist.Close() 81 | 82 | _, err = io.Copy(dist, src) 83 | if err != nil { 84 | return err 85 | } 86 | 87 | return nil 88 | } 89 | 90 | func exists(filepath string) bool { 91 | _, err := os.Stat(filepath) 92 | return !os.IsNotExist(err) 93 | } 94 | --------------------------------------------------------------------------------