diff --git a/.circleci/config.yml b/.circleci/config.yml index 8a4df7a..8f3712a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,30 +1,30 @@ environment: &environment environment: - - PROJECT_NAME: bake - - GO111MODULE: "on" + PROJECT_NAME: bake + GO111MODULE: "on" -defaults: &defaults +build_defaults: &build_defaults working_directory: /tmp/build docker: - - image: golang:1.12.4 + - image: golang:1.12.5 + <<: *environment + +lint_defaults: &lint_defaults + working_directory: /tmp/build + docker: + - image: golangci/golangci-lint:v1.16 <<: *environment version: 2.1 jobs: lint: - <<: *defaults + <<: *lint_defaults steps: - checkout - - run: go get -u golang.org/x/lint/golint - - run: - name: Run gofmt, enforce formatting - command: "! go fmt ./... 2>&1 | read" - - run: - name: Run golint, enforce styles - command: "golint -set_exit_status ./..." + - run: golangci-lint run --config=$CIRCLE_WORKING_DIRECTORY/.golangci.yml test: - <<: *defaults + <<: *build_defaults environment: TEST_RESULTS: /tmp/test-results steps: @@ -35,6 +35,7 @@ jobs: - run: mkdir -p $TEST_RESULTS - run: "go get -u gotest.tools/gotestsum" - run: "gotestsum --junitfile $TEST_RESULTS/unit-tests.xml" + - run: "go mod tidy" - save_cache: key: go-mod-v4-{{ checksum "go.sum" }}-test paths: @@ -42,24 +43,23 @@ jobs: - store_test_results: path: /tmp/test-results - build: - <<: *defaults + release: + docker: + - image: circleci/golang:1.12 steps: - checkout - - restore_cache: - keys: - - go-mod-v4-{{ checksum "go.sum" }} - - run: "GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build ." - - save_cache: - key: go-mod-v4-{{ checksum "go.sum" }} - paths: - - "/go/pkg/mod" + - run: curl -sL https://git.io/goreleaser | bash workflows: lint_and_build: jobs: - # - lint + - lint - test - - build: - requires: - - test + release: + jobs: + - release: + filters: + branches: + ignore: /.*/ + tags: + only: /v[0-9]+(\.[0-9]+)*(-.*)*/ diff --git a/.errcheck-exclude b/.errcheck-exclude new file mode 100644 index 0000000..f74cb4f --- /dev/null +++ b/.errcheck-exclude @@ -0,0 +1 @@ +(*github.com/spf13/cobra.Command).MarkFlagRequired \ No newline at end of file diff --git a/.golangci.dev.yml b/.golangci.dev.yml new file mode 100644 index 0000000..cbec3c2 --- /dev/null +++ b/.golangci.dev.yml @@ -0,0 +1,30 @@ +run: + # default concurrency is a available CPU number + concurrency: 8 + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 1m + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + # include test files or not, default is true + tests: true + skip-dirs: + - .circleci + - .github + +linters: + fast: true + +# all available settings of specific linters +linters-settings: + errcheck: + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + exclude: .errcheck-exclude + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - errcheck diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..ee7037f --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,41 @@ +run: + # default concurrency is a available CPU number + concurrency: 8 + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 30s + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + # include test files or not, default is true + tests: true + skip-dirs: + - .circleci + - .github + +# output configuration options +output: + # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" + format: colored-line-number + # print lines of code with issue, default is true + print-issued-lines: true + # print linter name in the end of issue text, default is true + print-linter-name: true + +linters: + fast: true + enable: + - goimports + +# all available settings of specific linters +linters-settings: + errcheck: + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + exclude: .errcheck-exclude + +issues: + # Excluding configuration per-path, per-linter, per-text and per-source + exclude-rules: + # Exclude some linters from running on tests files. + - path: _test\.go + linters: + - errcheck diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..5fda234 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,55 @@ +project_name: bake + +release: + github: + owner: breadtubetv + name: bake + +before: + hooks: + - go mod download + +builds: + - binary: bake + env: + - CGO_ENABLED=0 + - GO111MODULE=on + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - 386 + ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.ShortCommit}} -X main.date={{.Date}} + +archives: +- replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 + format: tar.gz + wrap_in_directory: true + format_overrides: + - goos: windows + format: zip + files: + - LICENSE + - README.md + +checksum: + name_template: '{{ .ProjectName }}-{{ .Version }}-checksums.txt' + +snapshot: + name_template: SNAPSHOT-{{.Commit}} + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + - README + - Merge branch \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f625e87 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +repos: +- name: Local Validations + repo: local + hooks: + - id: golangci-lint + name: golangci-lint + description: Fast linters runner for Go. + entry: golangci-lint run --fix + types: [go] + language: golang + pass_filenames: false + + - id: gomodtidy + name: gomodtidy + description: Tidy modules. + entry: GO111MODULE=on go mod tidy + types: [go] + language: golang + pass_filenames: false \ No newline at end of file diff --git a/README.md b/README.md index 7ea6ab3..379791f 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,28 @@ # BreadTube Bake CLI -The `bake` cli is a companion CLI to the [breadtubetv/breadtubetv](https://github.com/breadtubetv/breadtubetv) project. +The `bake` cli is a companion CLI to the [breadtubetv/breadtubetv](https://github.com/breadtubetv/breadtubetv) project. ## [Contributing](https://github.com/breadtubetv/bake/blob/master/CONTRIBUTING.md) Scripts are being written in Go, this keeps the scripting and operational language the same, provides cross system compatibility, and gives everyone an opportunity to learn a new programming language. -### Installation +## Installation -#### Installing Go +The compiled bake binary has no dependencies, so you can download your platforms release from the [release page](https://github.com/breadtubetv/bake/releases), pop it in your `$PATH` and off you go. -This is going to be dependent on your system, we recommend following https://golang.org/doc/install +If you want to build from source you will need the Go programming language installed, and your `$GOPATH` configured. -#### Developing - -You'll need a copy of the project in your `$GOPATH`. - -``` +```bash +# Enable Go 1.11+ module support +export GO111MODULE=on go get github.com/breadtubetv/bake -cd $GOPATH/github.com/breadtubetv/bake ``` -And you'll need to install bake's dependencies with: +This will install the binary into your `$GOPATH/bin` folder. If you don't already it's recommended you add this directory to your `$PATH`. -``` -go get -``` - -#### Installing - -This will put the `bake` command in your path: - -``` -go install -``` +## Usage -#### Configuring the `bake` CLI +### Configuring the `bake` CLI The `.bake.yaml` configuration file can be stored in the following locations: @@ -44,30 +31,91 @@ The `.bake.yaml` configuration file can be stored in the following locations: Current configuration options and default values: -- `projectRoot: "../"` : Directory of channel data files. +- `projectRoot: "../"` : Directory of channel data files. E.g. `$GOPATH/src/github.com/breadtubetv/breadtubetv/data/channels` -#### Importing a Channel +### Commands + +Once you have `bake` installed: + +#### Import a Channel + +```bash +bake channel import creator_slug youtube channel_url +``` + +#### Import a Video + +##### Using the Video ID + +```bash +bake import video --creator creator_slug --provider youtube --id VIDEO_ID +``` -You can run bake directly from the source like so: +##### Using the Video URL +```bash +bake import video --creator creator_slug --provider youtube --url https://VIDEO_URL ``` -go run main.go config youtube #follow prompts -go run main.go channel import contrapoints youtube https://www.youtube.com/user/contrapoints + +Note: The following formats are supported + +- https://www.youtube.com/watch?v=xspEtjnSfQA +- https://www.youtube.com/embed/xspEtjnSfQA + +## Contributing + +You'll need the Go programming language installed. We recommend version v1.12+. This is going to be dependent on your system, we recommend following + +Clone the repo and pull dependencies: + +```bash +# Enable Go 1.11 module support +export GO111MODULE=on +# Clone directory +git clone https://github.com/breadtubetv/bake +cd bake +# Download dependencies +go mod download ``` -Or if you've installed it: +> **NOTE:** The `spf13/cobra` generator CLI won't work if you don't clone the project into `$GOPATH`. This is not a requirement to develop for the project. + +### Linting & Pre-Commit +We recommend using [`golangci/golangci-lint`](https://github.com/golangci/golangci-lint) for linting. A development config (`.golangci.dev.yaml`) is provided. To use this config: + +```shell +golangci-lint run --config=.golangci.dev.yml ``` -bake config youtube #follow prompts -bake channel import contrapoints youtube https://www.youtube.com/user/contrapoints + +A `.pre-commit-config.yaml` is provided for pre-commit hooks using [`pre-commit/pre-commit`](https://github.com/pre-commit/pre-commit). + +### Submitting a PR + +We welcome PRs! The only thing we ask is that you ensure you keep the `go.mod` and `go.sum` files clean by running the following: + +```shell +GO111MODULE=on go mod tidy ``` -#### Testing +### Testing Bake has some very basic tests for now, they can be run with the standard go test command line: -``` +```bash go get -t ./... go test ./... ``` + +### Releasing + +Releasing is automated via `git tag` and CircleCI. Users with write permissions will be able to create tags. To create a new release: + +```shell +# vX.Y.Z needs to be a valid SemVer version number +git tag vX.Y.Z +git push --tags +``` + +CircleCI will do the rest! diff --git a/cmd/root.go b/cmd/root.go index d0cc13f..ba731a2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -40,7 +40,9 @@ var rootCmd = &cobra.Command{ // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { +func Execute(version, commit, date string) { + rootCmd.Version = version + rootCmd.SetVersionTemplate(fmt.Sprintf("Version: {{.Version}}, Commit: %s, Date: %s", commit, date)) if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/update.go b/cmd/update.go index 447c8f6..38d2e93 100644 --- a/cmd/update.go +++ b/cmd/update.go @@ -50,6 +50,9 @@ func updateChannelList(args []string) { } youtube, err := providers.FetchDetails(url) + if err != nil { + log.Fatalf("failed to update channel %s: %v", channel.Slug, err) + } channel.Providers["youtube"] = youtube @@ -72,6 +75,9 @@ func updateChannels() { } youtube, err := providers.FetchDetails(url) + if err != nil { + log.Fatalf("failed to update channel %s: %v", channel.Slug, err) + } channel.Providers["youtube"] = youtube diff --git a/go.mod b/go.mod index 8206b51..40f5418 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module github.com/breadtubetv/bake go 1.12 require ( + github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 github.com/spf13/cobra v0.0.3 github.com/spf13/viper v1.3.2 + github.com/stretchr/testify v1.2.2 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a google.golang.org/api v0.4.0 diff --git a/go.sum b/go.sum index 908f344..897ff03 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,30 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -27,6 +33,7 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= @@ -40,6 +47,7 @@ github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -65,6 +73,7 @@ golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -78,12 +87,14 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 google.golang.org/api v0.4.0 h1:KKgc1aqhV8wDPbDzlDtpvyjZFY3vjz85FP7p4wcQUyI= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19 h1:Lj2SnHtxkRGJDqnGaSjo+CCdIieEnwVazbOXILwQemk= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go index 362ecf7..64b8e61 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,13 @@ import ( "github.com/breadtubetv/bake/cmd" ) +var ( + // Populated by goreleaser during build + version = "master" + commit = "?" + date = "" +) + func main() { - cmd.Execute() + cmd.Execute(version, commit, date) } diff --git a/providers/youtube.go b/providers/youtube.go index ace0d74..085545c 100644 --- a/providers/youtube.go +++ b/providers/youtube.go @@ -192,7 +192,7 @@ func importChannel(slug string, channelURL *util.URL, projectRoot string) { log.Fatalf("Error saving channel '%s': %v", slug, err) } - util.CreateChannelVideoFolder(channel, projectRoot) + _ = util.CreateChannelVideoFolder(channel, projectRoot) err = util.CreateChannelPage(channel, projectRoot) if err != nil { @@ -233,8 +233,15 @@ func ImportVideo(id, creator, projectRoot string) error { if err != nil { return fmt.Errorf("couldn't marshal video data: %v", err) } - f.Write(data) - f.Sync() + _, err = f.Write(data) + if err != nil { + return fmt.Errorf("couldn't write to file: %s: %v", f.Name(), err) + } + + err = f.Sync() + if err != nil { + return fmt.Errorf("couldn't sync file: %s: %v", f.Name(), err) + } log.Printf("created video file %v", videoFile) err = channel.GetChannelPage(projectRoot).AddVideo(id, projectRoot) @@ -289,17 +296,6 @@ func handleError(err error, message string) { } } -const missingClientSecretsMessage = ` -Please configure OAuth 2.0 -To make this sample run, you need to populate the client_secrets.json file -found at: - %v -with information from the {{ Google Cloud Console }} -{{ https://cloud.google.com/console }} -For more information about the client_secrets.json file format, please visit: -https://developers.google.com/api-client-library/python/guide/aaa_client_secrets -` - // getClient uses a Context and Config to retrieve a Token // then generate a Client. It returns the generated Client. func getClient(scope string) *http.Client { @@ -356,13 +352,20 @@ func startWebServer() (codeCh chan string, err error) { } codeCh = make(chan string) - go http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - code := r.FormValue("code") - codeCh <- code // send code to OAuth flow - listener.Close() - w.Header().Set("Content-Type", "text/plain") - fmt.Fprintf(w, "Received code: %v\r\nYou can now safely close this browser window.", code) - })) + serve := func() { + err := http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + code := r.FormValue("code") + codeCh <- code // send code to OAuth flow + listener.Close() + w.Header().Set("Content-Type", "text/plain") + fmt.Fprintf(w, "Received code: %v\r\nYou can now safely close this browser window.", code) + })) + if err != nil { + panic(fmt.Sprintf("error starting server for OAuth callback: %v", err)) + } + } + + go serve() return codeCh, nil } @@ -387,7 +390,7 @@ func openURL(url string) error { // Exchange the authorization code for an access token func exchangeToken(config *oauth2.Config, code string) (*oauth2.Token, error) { - tok, err := config.Exchange(oauth2.NoContext, code) + tok, err := config.Exchange(context.TODO(), code) if err != nil { log.Fatalf("Unable to retrieve token %v", err) } @@ -440,7 +443,11 @@ func tokenCacheFile() (string, error) { return "", err } tokenCacheDir := filepath.Join(usr.HomeDir, ".credentials") - os.MkdirAll(tokenCacheDir, 0700) + err = os.MkdirAll(tokenCacheDir, 0700) + if err != nil { + return "", err + } + return filepath.Join(tokenCacheDir, url.QueryEscape("youtube-go.json")), err } @@ -468,5 +475,8 @@ func saveToken(file string, token *oauth2.Token) { log.Fatalf("Unable to cache oauth token: %v", err) } defer f.Close() - json.NewEncoder(f).Encode(token) + err = json.NewEncoder(f).Encode(token) + if err != nil { + log.Printf("couldn't store token: %v", err) + } } diff --git a/util/channel.go b/util/channel.go index 40f1b09..3de12fa 100644 --- a/util/channel.go +++ b/util/channel.go @@ -80,21 +80,18 @@ func (c *Channel) UnmarshalYAML(unmarshal func(interface{}) error) error { return fmt.Errorf("error parsing name: '%s', %T is not a string", value, value) } channel.Name = name - break case "slug": slug, ok := value.(string) if !ok { return fmt.Errorf("error parsing slug: '%s', %T is not a string", value, value) } channel.Slug = slug - break case "permalink": permalink, ok := value.(string) if !ok { return fmt.Errorf("error parsing permalink: '%s', %T is not a string", value, value) } channel.Permalink = permalink - break case "tags": // Handle non array tags if tags, ok := value.(string); ok { @@ -107,7 +104,6 @@ func (c *Channel) UnmarshalYAML(unmarshal func(interface{}) error) error { return fmt.Errorf("error parsing tags: '%s', %T is not a string", value, value) } channel.Tags = tags - break case "providers": providers, ok := value.(map[interface{}]interface{}) if !ok { @@ -116,10 +112,8 @@ func (c *Channel) UnmarshalYAML(unmarshal func(interface{}) error) error { if err := unmarshalProviders(providers, channel.Providers); err != nil { return err } - break default: channel.remnant[key] = value - break } } @@ -213,10 +207,6 @@ func unmarshalProvider(values map[interface{}]interface{}, out *Provider) error provider.Description = description break case "subscribers": - if value == nil { - continue - } - subscribers, ok := value.(int) if !ok { return fmt.Errorf("error parsing subscribers: '%s', %T is not an int", value, value) diff --git a/version.go b/version.go new file mode 100644 index 0000000..0311853 --- /dev/null +++ b/version.go @@ -0,0 +1,19 @@ +// +build go1.12 + +package main + +import ( + "fmt" + "runtime/debug" +) + +//nolint:gochecknoinits +func init() { + if info, available := debug.ReadBuildInfo(); available { + if date == "" && info.Main.Version != "(devel)" { + version = info.Main.Version + commit = fmt.Sprintf("(unknown, mod sum: %q)", info.Main.Sum) + date = "(unknown)" + } + } +}