diff --git a/.gitignore b/.gitignore index 5b90e79..65bcfc7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ go.work.sum # env file .env +# build artifacts +bin/ +dist/ \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..7203cb3 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "golang.go" + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index 724679d..97df9ad 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -App=skacksend +App=slacksend .PHONY: fmt vet test build run check diff --git a/README.md b/README.md index 60818d0..b0671d3 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Slackにメッセージを送信するツール - [Aiuto Docs](#aiuto-docs) - [Markdown](#markdown) - [Webserver](#webserver) + - [Deploy](#deploy) ## Environments @@ -82,3 +83,17 @@ go install golang.org/x/pkgsite/cmd/pkgsite@latest pkgsite ``` +## Deploy + +```sh +make build +# go build -o bin/slacksend ./cmd/slacksend +``` + +デバッグ情報を削ってビルドする場合 + +```sh +go build -o bin/slacksend \ + -ldflags "-s -w" \ + ./cmd/slacksend +``` diff --git a/cmd/slacksend/main.go b/cmd/slacksend/main.go index 26604ba..fca33d6 100644 --- a/cmd/slacksend/main.go +++ b/cmd/slacksend/main.go @@ -10,7 +10,6 @@ func hello() string { return "hello" } - func main() { os.Exit(cli.Run(os.Args)) } diff --git a/cmd/slacksend/main_test.go b/cmd/slacksend/main_test.go index c632ea1..f96a6a2 100644 --- a/cmd/slacksend/main_test.go +++ b/cmd/slacksend/main_test.go @@ -9,4 +9,4 @@ func TestHello(t *testing.T) { if got != want { t.Errorf("hello() = %q, want %q", got, want) } -} \ No newline at end of file +} diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 6721d42..19ec2ae 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -6,14 +6,17 @@ import ( "io" "os" "strings" + "time" + "gitea.pglikers.com/tools/slacksend/internal/slack" "gitea.pglikers.com/tools/slacksend/internal/version" ) type Options struct { ShowVersion bool WebhookURL string - TimeoutSec int + TimeoutSec int + Title string } func Run(args []string) int { @@ -31,7 +34,7 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { // other options fs.StringVar(&opt.WebhookURL, "webhook", "", "Slack Incoming Webhook URL (or env SLACK_WEBHOOK_URL)") fs.IntVar(&opt.TimeoutSec, "timeout", 10, "HTTP timeout seconds") - + fs.StringVar(&opt.Title, "title", "", "message title (shown as bold)") if err := fs.Parse(args[1:]); err != nil { if err == flag.ErrHelp { @@ -48,6 +51,12 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { return 0 } + if len(fs.Args()) == 0 && isTerminal(stdin) { + fmt.Fprintln(stderr, "message is required. provide args or pipe via stdin") + Usage(stderr) + return 2 + } + // webhook URL の解決: flag > env webhookURL := strings.TrimSpace(opt.WebhookURL) if webhookURL == "" { @@ -68,8 +77,17 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { return 2 } - // TODO: Slack送信(ここはあとで internal/slack に逃がす) - fmt.Fprintln(stdout, msg) + client := slack.WebhookClient{ + URL: webhookURL, + Timeout: time.Duration(opt.TimeoutSec) * time.Second, + } + + if err := client.Send(opt.Title, msg); err != nil { + fmt.Fprintln(stderr, "send failed:", err) + return 1 + } + + fmt.Fprintln(stdout, "ok") return 0 } @@ -84,3 +102,17 @@ func message(args []string, stdin io.Reader) (string, error) { return strings.TrimSpace(string(b)), nil } +// isTerminal reports whether the given reader is a character device (e.g., TTY). +func isTerminal(r io.Reader) bool { + fd, ok := r.(interface { + Stat() (os.FileInfo, error) + }) + if !ok { + return false + } + info, err := fd.Stat() + if err != nil { + return false + } + return info.Mode()&os.ModeCharDevice != 0 +} diff --git a/internal/cli/usage.go b/internal/cli/usage.go index 9a6b89d..7642f84 100644 --- a/internal/cli/usage.go +++ b/internal/cli/usage.go @@ -13,6 +13,8 @@ Usage: echo "message" | slacksend [options] Options: + --title