├── .dockerignore ├── .gitignore ├── .slugignore ├── .travis.yml ├── Dockerfile ├── Godeps ├── Godeps.json ├── Readme └── _workspace │ ├── .gitignore │ └── src │ ├── code.google.com │ └── p │ │ ├── go-uuid │ │ └── uuid │ │ │ ├── LICENSE │ │ │ ├── dce.go │ │ │ ├── doc.go │ │ │ ├── hash.go │ │ │ ├── node.go │ │ │ ├── time.go │ │ │ ├── util.go │ │ │ ├── uuid.go │ │ │ ├── uuid_test.go │ │ │ ├── version1.go │ │ │ └── version4.go │ │ └── goauth2 │ │ └── oauth │ │ ├── example │ │ └── oauthreq.go │ │ ├── jwt │ │ ├── example │ │ │ ├── example.client_secrets.json │ │ │ ├── example.pem │ │ │ └── main.go │ │ ├── jwt.go │ │ └── jwt_test.go │ │ ├── oauth.go │ │ └── oauth_test.go │ ├── github.com │ ├── codegangsta │ │ ├── cli │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── app.go │ │ │ ├── app_test.go │ │ │ ├── autocomplete │ │ │ │ ├── bash_autocomplete │ │ │ │ └── zsh_autocomplete │ │ │ ├── cli.go │ │ │ ├── cli_test.go │ │ │ ├── command.go │ │ │ ├── command_test.go │ │ │ ├── context.go │ │ │ ├── context_test.go │ │ │ ├── flag.go │ │ │ ├── flag_test.go │ │ │ ├── help.go │ │ │ └── helpers_test.go │ │ └── negroni │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── logger.go │ │ │ ├── logger_test.go │ │ │ ├── negroni.go │ │ │ ├── negroni_test.go │ │ │ ├── recovery.go │ │ │ ├── recovery_test.go │ │ │ ├── response_writer.go │ │ │ ├── response_writer_test.go │ │ │ ├── static.go │ │ │ └── static_test.go │ ├── dgrijalva │ │ └── jwt-go │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── VERSION_HISTORY.md │ │ │ ├── cmd │ │ │ └── jwt │ │ │ │ └── app.go │ │ │ ├── doc.go │ │ │ ├── hmac.go │ │ │ ├── hmac_test.go │ │ │ ├── jwt.go │ │ │ ├── jwt_test.go │ │ │ ├── rsa.go │ │ │ ├── rsa_test.go │ │ │ ├── rsa_utils.go │ │ │ ├── signing_method.go │ │ │ └── test │ │ │ ├── hmacTestKey │ │ │ ├── sample_key │ │ │ └── sample_key.pub │ ├── ejholmes │ │ ├── flock │ │ │ ├── README.md │ │ │ ├── flock.go │ │ │ └── flock_test.go │ │ └── hookshot │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── events │ │ │ ├── commit_comment.go │ │ │ ├── create.go │ │ │ ├── delete.go │ │ │ ├── deployment.go │ │ │ ├── deployment_status.go │ │ │ ├── events.go │ │ │ ├── fork.go │ │ │ ├── generate │ │ │ ├── gollum.go │ │ │ ├── issue_comment.go │ │ │ ├── issues.go │ │ │ ├── member.go │ │ │ ├── membership.go │ │ │ ├── page_build.go │ │ │ ├── ping.go │ │ │ ├── public.go │ │ │ ├── pull_request.go │ │ │ ├── pull_request_review_comment.go │ │ │ ├── push.go │ │ │ ├── release.go │ │ │ ├── repository.go │ │ │ ├── status.go │ │ │ ├── team_add.go │ │ │ └── watch.go │ │ │ ├── example_test.go │ │ │ ├── hooker │ │ │ ├── hooker.go │ │ │ └── hooker_test.go │ │ │ ├── hookshot.go │ │ │ └── hookshot_test.go │ ├── go-sql-driver │ │ └── mysql │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── AUTHORS │ │ │ ├── CHANGELOG.md │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── appengine.go │ │ │ ├── benchmark_test.go │ │ │ ├── buffer.go │ │ │ ├── collations.go │ │ │ ├── connection.go │ │ │ ├── const.go │ │ │ ├── driver.go │ │ │ ├── driver_test.go │ │ │ ├── errors.go │ │ │ ├── errors_test.go │ │ │ ├── infile.go │ │ │ ├── packets.go │ │ │ ├── result.go │ │ │ ├── rows.go │ │ │ ├── statement.go │ │ │ ├── transaction.go │ │ │ ├── utils.go │ │ │ └── utils_test.go │ ├── gocql │ │ └── gocql │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── AUTHORS │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── cass1batch_test.go │ │ │ ├── cassandra_test.go │ │ │ ├── cluster.go │ │ │ ├── compressor.go │ │ │ ├── compressor_test.go │ │ │ ├── conn.go │ │ │ ├── conn_test.go │ │ │ ├── connectionpool.go │ │ │ ├── doc.go │ │ │ ├── errors.go │ │ │ ├── errors_test.go │ │ │ ├── frame.go │ │ │ ├── frame_test.go │ │ │ ├── fuzz.go │ │ │ ├── helpers.go │ │ │ ├── host_source.go │ │ │ ├── integration.sh │ │ │ ├── marshal.go │ │ │ ├── marshal_test.go │ │ │ ├── metadata.go │ │ │ ├── metadata_test.go │ │ │ ├── policies.go │ │ │ ├── policies_test.go │ │ │ ├── session.go │ │ │ ├── session_test.go │ │ │ ├── testdata │ │ │ └── pki │ │ │ │ ├── .keystore │ │ │ │ ├── .truststore │ │ │ │ ├── ca.crt │ │ │ │ ├── ca.key │ │ │ │ ├── cassandra.crt │ │ │ │ ├── cassandra.key │ │ │ │ ├── gocql.crt │ │ │ │ └── gocql.key │ │ │ ├── token.go │ │ │ ├── token_test.go │ │ │ ├── topology.go │ │ │ ├── topology_test.go │ │ │ ├── tuple_test.go │ │ │ ├── udt_test.go │ │ │ ├── uuid.go │ │ │ ├── uuid_test.go │ │ │ ├── website │ │ │ ├── css │ │ │ │ ├── bootstrap-theme.css │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ ├── bootstrap.css │ │ │ │ └── bootstrap.min.css │ │ │ ├── favicon.ico │ │ │ ├── fonts │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ ├── gocql.png │ │ │ ├── index.html │ │ │ └── js │ │ │ │ ├── bootstrap.js │ │ │ │ └── bootstrap.min.js │ │ │ └── wiki_test.go │ ├── golang │ │ ├── groupcache │ │ │ └── lru │ │ │ │ ├── lru.go │ │ │ │ └── lru_test.go │ │ └── snappy │ │ │ └── snappy │ │ │ ├── decode.go │ │ │ ├── encode.go │ │ │ ├── snappy.go │ │ │ └── snappy_test.go │ ├── google │ │ ├── go-github │ │ │ └── github │ │ │ │ ├── activity.go │ │ │ │ ├── activity_events.go │ │ │ │ ├── activity_events_test.go │ │ │ │ ├── activity_notifications.go │ │ │ │ ├── activity_notifications_test.go │ │ │ │ ├── activity_star.go │ │ │ │ ├── activity_star_test.go │ │ │ │ ├── activity_watching.go │ │ │ │ ├── activity_watching_test.go │ │ │ │ ├── doc.go │ │ │ │ ├── gists.go │ │ │ │ ├── gists_comments.go │ │ │ │ ├── gists_comments_test.go │ │ │ │ ├── gists_test.go │ │ │ │ ├── git.go │ │ │ │ ├── git_blobs.go │ │ │ │ ├── git_blobs_test.go │ │ │ │ ├── git_commits.go │ │ │ │ ├── git_commits_test.go │ │ │ │ ├── git_refs.go │ │ │ │ ├── git_refs_test.go │ │ │ │ ├── git_tags.go │ │ │ │ ├── git_tags_test.go │ │ │ │ ├── git_trees.go │ │ │ │ ├── git_trees_test.go │ │ │ │ ├── github.go │ │ │ │ ├── github_test.go │ │ │ │ ├── gitignore.go │ │ │ │ ├── gitignore_test.go │ │ │ │ ├── issues.go │ │ │ │ ├── issues_assignees.go │ │ │ │ ├── issues_assignees_test.go │ │ │ │ ├── issues_comments.go │ │ │ │ ├── issues_comments_test.go │ │ │ │ ├── issues_events.go │ │ │ │ ├── issues_events_test.go │ │ │ │ ├── issues_labels.go │ │ │ │ ├── issues_labels_test.go │ │ │ │ ├── issues_milestones.go │ │ │ │ ├── issues_milestones_test.go │ │ │ │ ├── issues_test.go │ │ │ │ ├── misc.go │ │ │ │ ├── misc_test.go │ │ │ │ ├── orgs.go │ │ │ │ ├── orgs_members.go │ │ │ │ ├── orgs_members_test.go │ │ │ │ ├── orgs_teams.go │ │ │ │ ├── orgs_teams_test.go │ │ │ │ ├── orgs_test.go │ │ │ │ ├── pulls.go │ │ │ │ ├── pulls_comments.go │ │ │ │ ├── pulls_comments_test.go │ │ │ │ ├── pulls_test.go │ │ │ │ ├── repos.go │ │ │ │ ├── repos_collaborators.go │ │ │ │ ├── repos_collaborators_test.go │ │ │ │ ├── repos_comments.go │ │ │ │ ├── repos_comments_test.go │ │ │ │ ├── repos_commits.go │ │ │ │ ├── repos_commits_test.go │ │ │ │ ├── repos_contents.go │ │ │ │ ├── repos_contents_test.go │ │ │ │ ├── repos_deployments.go │ │ │ │ ├── repos_deployments_test.go │ │ │ │ ├── repos_forks.go │ │ │ │ ├── repos_forks_test.go │ │ │ │ ├── repos_hooks.go │ │ │ │ ├── repos_hooks_test.go │ │ │ │ ├── repos_keys.go │ │ │ │ ├── repos_keys_test.go │ │ │ │ ├── repos_merging.go │ │ │ │ ├── repos_merging_test.go │ │ │ │ ├── repos_pages.go │ │ │ │ ├── repos_pages_test.go │ │ │ │ ├── repos_releases.go │ │ │ │ ├── repos_releases_test.go │ │ │ │ ├── repos_stats.go │ │ │ │ ├── repos_stats_test.go │ │ │ │ ├── repos_statuses.go │ │ │ │ ├── repos_statuses_test.go │ │ │ │ ├── repos_test.go │ │ │ │ ├── search.go │ │ │ │ ├── search_test.go │ │ │ │ ├── strings.go │ │ │ │ ├── strings_test.go │ │ │ │ ├── timestamp.go │ │ │ │ ├── timestamp_test.go │ │ │ │ ├── users.go │ │ │ │ ├── users_administration.go │ │ │ │ ├── users_administration_test.go │ │ │ │ ├── users_emails.go │ │ │ │ ├── users_emails_test.go │ │ │ │ ├── users_followers.go │ │ │ │ ├── users_followers_test.go │ │ │ │ ├── users_keys.go │ │ │ │ ├── users_keys_test.go │ │ │ │ └── users_test.go │ │ └── go-querystring │ │ │ └── query │ │ │ ├── encode.go │ │ │ └── encode_test.go │ ├── gorilla │ │ ├── context │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── context.go │ │ │ ├── context_test.go │ │ │ └── doc.go │ │ └── mux │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bench_test.go │ │ │ ├── doc.go │ │ │ ├── mux.go │ │ │ ├── mux_test.go │ │ │ ├── old_test.go │ │ │ ├── regexp.go │ │ │ └── route.go │ ├── joshk │ │ └── pusher │ │ │ ├── .gitignore │ │ │ ├── CONTRIBUTING.md │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── examples │ │ │ ├── all_channels.go │ │ │ ├── basic_publish.go │ │ │ ├── channel.go │ │ │ ├── filtered_channels.go │ │ │ ├── multi_publish.go │ │ │ └── users.go │ │ │ ├── signature.go │ │ │ └── signature_test.go │ ├── kr │ │ ├── githubauth │ │ │ ├── Readme.md │ │ │ └── githubauth.go │ │ └── session │ │ │ ├── Readme │ │ │ └── session.go │ ├── lib │ │ └── pq │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE.md │ │ │ ├── README.md │ │ │ ├── bench_test.go │ │ │ ├── buf.go │ │ │ ├── certs │ │ │ ├── README │ │ │ ├── postgresql.crt │ │ │ ├── postgresql.key │ │ │ ├── root.crt │ │ │ ├── server.crt │ │ │ └── server.key │ │ │ ├── conn.go │ │ │ ├── conn_test.go │ │ │ ├── copy.go │ │ │ ├── copy_test.go │ │ │ ├── doc.go │ │ │ ├── encode.go │ │ │ ├── encode_test.go │ │ │ ├── error.go │ │ │ ├── hstore │ │ │ ├── hstore.go │ │ │ └── hstore_test.go │ │ │ ├── listen_example │ │ │ └── doc.go │ │ │ ├── notify.go │ │ │ ├── notify_test.go │ │ │ ├── oid │ │ │ ├── doc.go │ │ │ ├── gen.go │ │ │ └── types.go │ │ │ ├── ssl_test.go │ │ │ ├── url.go │ │ │ ├── url_test.go │ │ │ ├── user_posix.go │ │ │ └── user_windows.go │ └── mattes │ │ └── migrate │ │ ├── driver │ │ ├── bash │ │ │ ├── README.md │ │ │ ├── bash.go │ │ │ └── bash_test.go │ │ ├── cassandra │ │ │ ├── README.md │ │ │ ├── cassandra.go │ │ │ └── cassandra_test.go │ │ ├── driver.go │ │ ├── driver_test.go │ │ ├── mysql │ │ │ ├── README.md │ │ │ ├── mysql.go │ │ │ └── mysql_test.go │ │ └── postgres │ │ │ ├── README.md │ │ │ ├── postgres.go │ │ │ └── postgres_test.go │ │ ├── file │ │ ├── file.go │ │ └── file_test.go │ │ ├── migrate │ │ ├── direction │ │ │ └── direction.go │ │ ├── migrate.go │ │ └── migrate_test.go │ │ └── pipe │ │ └── pipe.go │ ├── golang.org │ └── x │ │ ├── crypto │ │ ├── nacl │ │ │ └── secretbox │ │ │ │ ├── secretbox.go │ │ │ │ └── secretbox_test.go │ │ ├── poly1305 │ │ │ ├── const_amd64.s │ │ │ ├── poly1305.go │ │ │ ├── poly1305_amd64.s │ │ │ ├── poly1305_test.go │ │ │ ├── sum_amd64.go │ │ │ └── sum_ref.go │ │ └── salsa20 │ │ │ └── salsa │ │ │ ├── hsalsa20.go │ │ │ ├── salsa2020_amd64.s │ │ │ ├── salsa208.go │ │ │ ├── salsa20_amd64.go │ │ │ ├── salsa20_ref.go │ │ │ └── salsa_test.go │ │ ├── net │ │ └── context │ │ │ ├── context.go │ │ │ ├── context_test.go │ │ │ └── withtimeout_test.go │ │ └── oauth2 │ │ ├── .travis.yml │ │ ├── AUTHORS │ │ ├── CONTRIBUTING.md │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── README.md │ │ ├── client_appengine.go │ │ ├── example_test.go │ │ ├── facebook │ │ └── facebook.go │ │ ├── github │ │ └── github.go │ │ ├── google │ │ ├── appengine.go │ │ ├── appengine_hook.go │ │ ├── default.go │ │ ├── example_test.go │ │ ├── google.go │ │ ├── google_test.go │ │ ├── sdk.go │ │ ├── sdk_test.go │ │ └── testdata │ │ │ └── gcloud │ │ │ ├── credentials │ │ │ └── properties │ │ ├── internal │ │ ├── oauth2.go │ │ └── oauth2_test.go │ │ ├── jws │ │ └── jws.go │ │ ├── jwt │ │ ├── example_test.go │ │ ├── jwt.go │ │ └── jwt_test.go │ │ ├── linkedin │ │ └── linkedin.go │ │ ├── oauth2.go │ │ ├── oauth2_test.go │ │ ├── odnoklassniki │ │ └── odnoklassniki.go │ │ ├── paypal │ │ └── paypal.go │ │ ├── token.go │ │ ├── token_test.go │ │ ├── transport.go │ │ ├── transport_test.go │ │ └── vk │ │ └── vk.go │ ├── gopkg.in │ └── gorp.v1 │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── README.md │ │ ├── dialect.go │ │ ├── errors.go │ │ ├── gorp.go │ │ ├── gorp_test.go │ │ └── test_all.sh │ └── speter.net │ └── go │ └── exp │ └── math │ └── dec │ └── inf │ ├── LICENSE │ ├── benchmark_test.go │ ├── dec.go │ ├── dec_go1_2_test.go │ ├── dec_internal_test.go │ ├── dec_test.go │ ├── example_test.go │ ├── rounder.go │ ├── rounder_example_test.go │ └── rounder_test.go ├── Makefile ├── Procfile ├── README.md ├── bin └── build ├── circle.yml ├── client.go ├── cmd ├── fake │ └── main.go └── tugboat │ ├── main.go │ ├── migrate.go │ ├── server.go │ └── tokens.go ├── db.go ├── deployments.go ├── deployments_test.go ├── docker-compose.yml ├── frontend ├── .gitignore ├── README.md ├── dist │ ├── app.css │ ├── app.js │ └── index.html ├── frontend.go ├── gulpfile.js ├── index.html ├── javascripts │ ├── ansi_up.js │ ├── app.js │ ├── controllers.js │ ├── directives.js │ ├── filters.js │ └── services.js ├── package.json ├── stylesheets │ ├── _job.scss │ ├── _spinner.scss │ └── app.scss └── templates │ ├── content.html │ ├── header.html │ ├── jobs.html │ └── jobs │ ├── detail.html │ └── list.html ├── logs.go ├── logs_test.go ├── migrations ├── 0001_initial_schema.down.sql ├── 0001_initial_schema.up.sql ├── 0002_add_user_column.down.sql └── 0002_add_user_column.up.sql ├── pkg ├── README.md ├── heroku │ ├── heroku.go │ ├── schema.json │ └── transport.go ├── hooker │ ├── hooker.go │ └── hooker_test.go └── pusherauth │ ├── auth.go │ └── auth_test.go ├── provider.go ├── provider ├── empire │ ├── client.go │ └── empire.go ├── fake │ └── fake.go └── heroku │ ├── heroku.go │ └── heroku_test.go ├── provider_test.go ├── pusher.go ├── pusher_test.go ├── server ├── api │ ├── api.go │ └── deployments.go ├── github │ └── github.go └── server.go ├── status.go ├── store.go ├── tests ├── api │ ├── api_test.go │ └── test-fixtures │ │ └── deployment.json └── github │ ├── github_test.go │ └── test-fixtures │ ├── deployment │ ├── failure.json │ └── ok.json │ └── deployment_status │ └── ok.json ├── tokens.go ├── tugboat.go ├── tugboat_test.go └── tugboattest └── test.go /.dockerignore: -------------------------------------------------------------------------------- 1 | Godeps/_workspace/pkg 2 | build 3 | .git 4 | frontend/node_modules 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .env 3 | -------------------------------------------------------------------------------- /.slugignore: -------------------------------------------------------------------------------- 1 | tests 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | addons: 4 | postgresql: "9.4" 5 | 6 | services: 7 | - postgresql 8 | 9 | go: 10 | - 1.4 11 | 12 | before_install: 13 | - go install -a -race std 14 | - go get github.com/tools/godep 15 | - export PATH=$HOME/gopath/bin:$PATH 16 | - createdb tugboat 17 | - godep go install ./cmd/... 18 | - tugboat migrate 19 | 20 | script: 21 | - make cmd 22 | - godep go test -race ./... 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.1 2 | MAINTAINER Eric Holmes 3 | 4 | COPY ./ /go/src/github.com/remind101/tugboat 5 | COPY ./bin/build /build 6 | RUN /build 7 | WORKDIR /var/run/tugboat 8 | 9 | CMD ["/bin/tugboat", "server"] 10 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /pkg 2 | /bin 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/go-uuid/uuid/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/go-uuid/uuid/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // The uuid package generates and inspects UUIDs. 6 | // 7 | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services. 8 | package uuid 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/go-uuid/uuid/hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "crypto/md5" 9 | "crypto/sha1" 10 | "hash" 11 | ) 12 | 13 | // Well known Name Space IDs and UUIDs 14 | var ( 15 | NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 16 | NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") 17 | NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") 18 | NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") 19 | NIL = Parse("00000000-0000-0000-0000-000000000000") 20 | ) 21 | 22 | // NewHash returns a new UUID dervied from the hash of space concatenated with 23 | // data generated by h. The hash should be at least 16 byte in length. The 24 | // first 16 bytes of the hash are used to form the UUID. The version of the 25 | // UUID will be the lower 4 bits of version. NewHash is used to implement 26 | // NewMD5 and NewSHA1. 27 | func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { 28 | h.Reset() 29 | h.Write(space) 30 | h.Write([]byte(data)) 31 | s := h.Sum(nil) 32 | uuid := make([]byte, 16) 33 | copy(uuid, s) 34 | uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) 35 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant 36 | return uuid 37 | } 38 | 39 | // NewMD5 returns a new MD5 (Version 3) UUID based on the 40 | // supplied name space and data. 41 | // 42 | // NewHash(md5.New(), space, data, 3) 43 | func NewMD5(space UUID, data []byte) UUID { 44 | return NewHash(md5.New(), space, data, 3) 45 | } 46 | 47 | // NewSHA1 returns a new SHA1 (Version 5) UUID based on the 48 | // supplied name space and data. 49 | // 50 | // NewHash(sha1.New(), space, data, 5) 51 | func NewSHA1(space UUID, data []byte) UUID { 52 | return NewHash(sha1.New(), space, data, 5) 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/go-uuid/uuid/version1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | ) 10 | 11 | // NewUUID returns a Version 1 UUID based on the current NodeID and clock 12 | // sequence, and the current time. If the NodeID has not been set by SetNodeID 13 | // or SetNodeInterface then it will be set automatically. If the NodeID cannot 14 | // be set NewUUID returns nil. If clock sequence has not been set by 15 | // SetClockSequence then it will be set automatically. If GetTime fails to 16 | // return the current NewUUID returns nil. 17 | func NewUUID() UUID { 18 | if nodeID == nil { 19 | SetNodeInterface("") 20 | } 21 | 22 | now, err := GetTime() 23 | if err != nil { 24 | return nil 25 | } 26 | 27 | uuid := make([]byte, 16) 28 | 29 | time_low := uint32(now & 0xffffffff) 30 | time_mid := uint16((now >> 32) & 0xffff) 31 | time_hi := uint16((now >> 48) & 0x0fff) 32 | time_hi |= 0x1000 // Version 1 33 | 34 | binary.BigEndian.PutUint32(uuid[0:], time_low) 35 | binary.BigEndian.PutUint16(uuid[4:], time_mid) 36 | binary.BigEndian.PutUint16(uuid[6:], time_hi) 37 | binary.BigEndian.PutUint16(uuid[8:], clock_seq) 38 | copy(uuid[10:], nodeID) 39 | 40 | return uuid 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/go-uuid/uuid/version4.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | // Random returns a Random (Version 4) UUID or panics. 8 | // 9 | // The strength of the UUIDs is based on the strength of the crypto/rand 10 | // package. 11 | // 12 | // A note about uniqueness derived from from the UUID Wikipedia entry: 13 | // 14 | // Randomly generated UUIDs have 122 random bits. One's annual risk of being 15 | // hit by a meteorite is estimated to be one chance in 17 billion, that 16 | // means the probability is about 0.00000000006 (6 × 10−11), 17 | // equivalent to the odds of creating a few tens of trillions of UUIDs in a 18 | // year and having one duplicate. 19 | func NewRandom() UUID { 20 | uuid := make([]byte, 16) 21 | randomBits([]byte(uuid)) 22 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 23 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 24 | return uuid 25 | } 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.client_secrets.json: -------------------------------------------------------------------------------- 1 | {"web":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"XXXXXXXXXXXX@developer.gserviceaccount.com","client_x509_cert_url":"https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXX@developer.gserviceaccount.com","client_id":"XXXXXXXXXXXX.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}} 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/code.google.com/p/goauth2/oauth/jwt/example/example.pem: -------------------------------------------------------------------------------- 1 | Bag Attributes 2 | friendlyName: privatekey 3 | localKeyID: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4 | Key Attributes: 5 | -----BEGIN PRIVATE KEY----- 6 | XXXXxyXXXXXXXxxyxxxX9y0XXYXXXXYXXxXyxxXxXxXXXyXXXXx4yx1xy1xyYxxY 7 | 1XxYy38YxXxxxyXxyyxx+xxxxyx1Y1xYx7yx2/Y1XyyXYYYxY5YXxX0xY/Y642yX 8 | zYYxYXzXYxY0Y8y9YxyYXxxX40YyXxxXX4XXxx7XxXxxXyXxYYXxXyxX5XY0Yy2X 9 | 1YX0XXyy6YXyXx9XxXxyXX9XXYXxXxXXXXXXxYXYY3Y8Yy311XYYY81XyY14Xyyx 10 | xXyx7xxXXXxxxxyyyX4YYYXyYyYXyxX4XYXYyxXYyx9xy23xXYyXyxYxXxx1XXXY 11 | y98yX6yYxyyyX4Xyx1Xy/0yxxYxXxYYx2xx7yYXXXxYXXXxyXyyYYxx5XX2xxyxy 12 | y6Yyyx0XX3YYYyx9YYXXXX7y0yxXXy+90XYz1y2xyx7yXxX+8X0xYxXXYxxyxYYy 13 | YXx8Yy4yX0Xyxxx6yYX92yxy1YYYzyyyyxy55x/yyXXXYYXYXXzXXxYYxyXY8XXX 14 | +y9+yXxX7XxxyYYxxXYxyY623xxXxYX59x5Y6yYyXYY4YxXXYXXXYxXYxXxXXx6x 15 | YXX7XxXX2X0XY7YXyYy1XXxYXxXxYY1xXXxxxyy+07zXYxYxxXyyxxyxXx1XYy5X 16 | 5XYzyxYxXXYyX9XX7xX8xXxx+XXYyYXXXX5YY1x8Yxyx54Xy/1XXyyYXY5YxYyxY 17 | XyyxXyX/YxxXXXxXXYXxyxx63xX/xxyYXXyYzx0XY+YxX5xyYyyxxxXXYX/94XXy 18 | Xx63xYxXyXY3/XXxyyXX15XXXyz08XYY5YYXY/YXy/96x68XyyXXxYyXy4xYXx5x 19 | 7yxxyxxYxXxyx3y= 20 | -----END PRIVATE KEY----- 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 1.1 3 | 4 | script: 5 | - go vet ./... 6 | - go test -v ./... 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Jeremy Saenz 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/bash_autocomplete: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | _cli_bash_autocomplete() { 4 | local cur prev opts base 5 | COMPREPLY=() 6 | cur="${COMP_WORDS[COMP_CWORD]}" 7 | prev="${COMP_WORDS[COMP_CWORD-1]}" 8 | opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion ) 9 | COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) 10 | return 0 11 | } 12 | 13 | complete -F _cli_bash_autocomplete $PROG -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/autocomplete/zsh_autocomplete: -------------------------------------------------------------------------------- 1 | autoload -U compinit && compinit 2 | autoload -U bashcompinit && bashcompinit 3 | 4 | script_dir=$(dirname $0) 5 | source ${script_dir}/bash_autocomplete 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/command_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "flag" 5 | "testing" 6 | 7 | "github.com/codegangsta/cli" 8 | ) 9 | 10 | func TestCommandDoNotIgnoreFlags(t *testing.T) { 11 | app := cli.NewApp() 12 | set := flag.NewFlagSet("test", 0) 13 | test := []string{"blah", "blah", "-break"} 14 | set.Parse(test) 15 | 16 | c := cli.NewContext(app, set, set) 17 | 18 | command := cli.Command{ 19 | Name: "test-cmd", 20 | ShortName: "tc", 21 | Usage: "this is for testing", 22 | Description: "testing", 23 | Action: func(_ *cli.Context) {}, 24 | } 25 | err := command.Run(c) 26 | 27 | expect(t, err.Error(), "flag provided but not defined: -break") 28 | } 29 | 30 | func TestCommandIgnoreFlags(t *testing.T) { 31 | app := cli.NewApp() 32 | set := flag.NewFlagSet("test", 0) 33 | test := []string{"blah", "blah"} 34 | set.Parse(test) 35 | 36 | c := cli.NewContext(app, set, set) 37 | 38 | command := cli.Command{ 39 | Name: "test-cmd", 40 | ShortName: "tc", 41 | Usage: "this is for testing", 42 | Description: "testing", 43 | Action: func(_ *cli.Context) {}, 44 | SkipFlagParsing: true, 45 | } 46 | err := command.Run(c) 47 | 48 | expect(t, err, nil) 49 | } 50 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/cli/helpers_test.go: -------------------------------------------------------------------------------- 1 | package cli_test 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | /* Test Helpers */ 9 | func expect(t *testing.T, a interface{}, b interface{}) { 10 | if a != b { 11 | t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) 12 | } 13 | } 14 | 15 | func refute(t *testing.T, a interface{}, b interface{}) { 16 | if a == b { 17 | t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jeremy Saenz 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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/doc.go: -------------------------------------------------------------------------------- 1 | // Package negroni is an idiomatic approach to web middleware in Go. It is tiny, non-intrusive, and encourages use of net/http Handlers. 2 | // 3 | // If you like the idea of Martini, but you think it contains too much magic, then Negroni is a great fit. 4 | // 5 | // For a full guide visit http://github.com/codegangsta/negroni 6 | // 7 | // package main 8 | // 9 | // import ( 10 | // "github.com/codegangsta/negroni" 11 | // "net/http" 12 | // "fmt" 13 | // ) 14 | // 15 | // func main() { 16 | // mux := http.NewServeMux() 17 | // mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 18 | // fmt.Fprintf(w, "Welcome to the home page!") 19 | // }) 20 | // 21 | // n := negroni.Classic() 22 | // n.UseHandler(mux) 23 | // n.Run(":3000") 24 | // } 25 | package negroni 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/logger.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "os" 7 | "time" 8 | ) 9 | 10 | // Logger is a middleware handler that logs the request as it goes in and the response as it goes out. 11 | type Logger struct { 12 | // Logger inherits from log.Logger used to log messages with the Logger middleware 13 | *log.Logger 14 | } 15 | 16 | // NewLogger returns a new Logger instance 17 | func NewLogger() *Logger { 18 | return &Logger{log.New(os.Stdout, "[negroni] ", 0)} 19 | } 20 | 21 | func (l *Logger) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 22 | start := time.Now() 23 | l.Printf("Started %s %s", r.Method, r.URL.Path) 24 | 25 | next(rw, r) 26 | 27 | res := rw.(ResponseWriter) 28 | l.Printf("Completed %v %s in %v", res.Status(), http.StatusText(res.Status()), time.Since(start)) 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/logger_test.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "net/http" 7 | "net/http/httptest" 8 | "testing" 9 | ) 10 | 11 | func Test_Logger(t *testing.T) { 12 | buff := bytes.NewBufferString("") 13 | recorder := httptest.NewRecorder() 14 | 15 | l := NewLogger() 16 | l.Logger = log.New(buff, "[negroni] ", 0) 17 | 18 | n := New() 19 | // replace log for testing 20 | n.Use(l) 21 | n.UseHandler(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { 22 | rw.WriteHeader(http.StatusNotFound) 23 | })) 24 | 25 | req, err := http.NewRequest("GET", "http://localhost:3000/foobar", nil) 26 | if err != nil { 27 | t.Error(err) 28 | } 29 | 30 | n.ServeHTTP(recorder, req) 31 | expect(t, recorder.Code, http.StatusNotFound) 32 | refute(t, len(buff.String()), 0) 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/recovery.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/http" 7 | "os" 8 | "runtime" 9 | ) 10 | 11 | // Recovery is a Negroni middleware that recovers from any panics and writes a 500 if there was one. 12 | type Recovery struct { 13 | Logger *log.Logger 14 | PrintStack bool 15 | StackAll bool 16 | StackSize int 17 | } 18 | 19 | // NewRecovery returns a new instance of Recovery 20 | func NewRecovery() *Recovery { 21 | return &Recovery{ 22 | Logger: log.New(os.Stdout, "[negroni] ", 0), 23 | PrintStack: true, 24 | StackAll: false, 25 | StackSize: 1024 * 8, 26 | } 27 | } 28 | 29 | func (rec *Recovery) ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) { 30 | defer func() { 31 | if err := recover(); err != nil { 32 | rw.WriteHeader(http.StatusInternalServerError) 33 | stack := make([]byte, rec.StackSize) 34 | stack = stack[:runtime.Stack(stack, rec.StackAll)] 35 | 36 | f := "PANIC: %s\n%s" 37 | rec.Logger.Printf(f, err, stack) 38 | 39 | if rec.PrintStack { 40 | fmt.Fprintf(rw, f, err, stack) 41 | } 42 | } 43 | }() 44 | 45 | next(rw, r) 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/codegangsta/negroni/recovery_test.go: -------------------------------------------------------------------------------- 1 | package negroni 2 | 3 | import ( 4 | "bytes" 5 | "log" 6 | "net/http" 7 | "net/http/httptest" 8 | "testing" 9 | ) 10 | 11 | func TestRecovery(t *testing.T) { 12 | buff := bytes.NewBufferString("") 13 | recorder := httptest.NewRecorder() 14 | 15 | rec := NewRecovery() 16 | rec.Logger = log.New(buff, "[negroni] ", 0) 17 | 18 | n := New() 19 | // replace log for testing 20 | n.Use(rec) 21 | n.UseHandler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 22 | panic("here is a panic!") 23 | })) 24 | n.ServeHTTP(recorder, (*http.Request)(nil)) 25 | expect(t, recorder.Code, http.StatusInternalServerError) 26 | refute(t, recorder.Body.Len(), 0) 27 | refute(t, len(buff.String()), 0) 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | bin 3 | 4 | 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Dave Grijalva 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/doc.go: -------------------------------------------------------------------------------- 1 | // Package jwt is a Go implementation of JSON Web Tokens: http://self-issued.info/docs/draft-jones-json-web-token.html 2 | // 3 | // See README.md for more info. 4 | package jwt 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_utils.go: -------------------------------------------------------------------------------- 1 | package jwt 2 | 3 | import ( 4 | "crypto/rsa" 5 | "crypto/x509" 6 | "encoding/pem" 7 | "errors" 8 | ) 9 | 10 | // Parse PEM encoded PKCS1 or PKCS8 private key 11 | func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { 12 | var err error 13 | 14 | // Parse PEM block 15 | var block *pem.Block 16 | if block, _ = pem.Decode(key); block == nil { 17 | return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") 18 | } 19 | 20 | var parsedKey interface{} 21 | if parsedKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { 22 | if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { 23 | return nil, err 24 | } 25 | } 26 | 27 | var pkey *rsa.PrivateKey 28 | var ok bool 29 | if pkey, ok = parsedKey.(*rsa.PrivateKey); !ok { 30 | return nil, errors.New("Key is not a valid RSA private key") 31 | } 32 | 33 | return pkey, nil 34 | } 35 | 36 | // Parse PEM encoded PKCS1 or PKCS8 public key 37 | func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { 38 | var err error 39 | 40 | // Parse PEM block 41 | var block *pem.Block 42 | if block, _ = pem.Decode(key); block == nil { 43 | return nil, errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key") 44 | } 45 | 46 | // Parse the key 47 | var parsedKey interface{} 48 | if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil { 49 | if cert, err := x509.ParseCertificate(block.Bytes); err == nil { 50 | parsedKey = cert.PublicKey 51 | } else { 52 | return nil, err 53 | } 54 | } 55 | 56 | var pkey *rsa.PublicKey 57 | var ok bool 58 | if pkey, ok = parsedKey.(*rsa.PublicKey); !ok { 59 | return nil, errors.New("Key is not a valid RSA public key") 60 | } 61 | 62 | return pkey, nil 63 | } 64 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/signing_method.go: -------------------------------------------------------------------------------- 1 | package jwt 2 | 3 | var signingMethods = map[string]func() SigningMethod{} 4 | 5 | // Signing method 6 | type SigningMethod interface { 7 | Verify(signingString, signature string, key interface{}) error 8 | Sign(signingString string, key interface{}) (string, error) 9 | Alg() string 10 | } 11 | 12 | // Register the "alg" name and a factory function for signing method. 13 | // This is typically done during init() in the method's implementation 14 | func RegisterSigningMethod(alg string, f func() SigningMethod) { 15 | signingMethods[alg] = f 16 | } 17 | 18 | // Get a signing method from an "alg" string 19 | func GetSigningMethod(alg string) (method SigningMethod) { 20 | if methodF, ok := signingMethods[alg]; ok { 21 | method = methodF() 22 | } 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEU/wT8RDtn 3 | SgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7mCpz9Er5qLaMXJwZxzHzAahlfA0i 4 | cqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBpHssPnpYGIn20ZZuNlX2BrClciHhC 5 | PUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2XrHhR+1DcKJzQBSTAGnpYVaqpsAR 6 | ap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3bODIRe1AuTyHceAbewn8b462yEWKA 7 | Rdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy7wIDAQABAoIBAQCwia1k7+2oZ2d3 8 | n6agCAbqIE1QXfCmh41ZqJHbOY3oRQG3X1wpcGH4Gk+O+zDVTV2JszdcOt7E5dAy 9 | MaomETAhRxB7hlIOnEN7WKm+dGNrKRvV0wDU5ReFMRHg31/Lnu8c+5BvGjZX+ky9 10 | POIhFFYJqwCRlopGSUIxmVj5rSgtzk3iWOQXr+ah1bjEXvlxDOWkHN6YfpV5ThdE 11 | KdBIPGEVqa63r9n2h+qazKrtiRqJqGnOrHzOECYbRFYhexsNFz7YT02xdfSHn7gM 12 | IvabDDP/Qp0PjE1jdouiMaFHYnLBbgvlnZW9yuVf/rpXTUq/njxIXMmvmEyyvSDn 13 | FcFikB8pAoGBAPF77hK4m3/rdGT7X8a/gwvZ2R121aBcdPwEaUhvj/36dx596zvY 14 | mEOjrWfZhF083/nYWE2kVquj2wjs+otCLfifEEgXcVPTnEOPO9Zg3uNSL0nNQghj 15 | FuD3iGLTUBCtM66oTe0jLSslHe8gLGEQqyMzHOzYxNqibxcOZIe8Qt0NAoGBAO+U 16 | I5+XWjWEgDmvyC3TrOSf/KCGjtu0TSv30ipv27bDLMrpvPmD/5lpptTFwcxvVhCs 17 | 2b+chCjlghFSWFbBULBrfci2FtliClOVMYrlNBdUSJhf3aYSG2Doe6Bgt1n2CpNn 18 | /iu37Y3NfemZBJA7hNl4dYe+f+uzM87cdQ214+jrAoGAXA0XxX8ll2+ToOLJsaNT 19 | OvNB9h9Uc5qK5X5w+7G7O998BN2PC/MWp8H+2fVqpXgNENpNXttkRm1hk1dych86 20 | EunfdPuqsX+as44oCyJGFHVBnWpm33eWQw9YqANRI+pCJzP08I5WK3osnPiwshd+ 21 | hR54yjgfYhBFNI7B95PmEQkCgYBzFSz7h1+s34Ycr8SvxsOBWxymG5zaCsUbPsL0 22 | 4aCgLScCHb9J+E86aVbbVFdglYa5Id7DPTL61ixhl7WZjujspeXZGSbmq0Kcnckb 23 | mDgqkLECiOJW2NHP/j0McAkDLL4tysF8TLDO8gvuvzNC+WQ6drO2ThrypLVZQ+ry 24 | eBIPmwKBgEZxhqa0gVvHQG/7Od69KWj4eJP28kq13RhKay8JOoN0vPmspXJo1HY3 25 | CKuHRG+AP579dncdUnOMvfXOtkdM4vk0+hWASBQzM9xzVcztCa+koAugjVaLS9A+ 26 | 9uQoqEeVNTckxx0S2bYevRy7hGQmUJTyQm3j1zEUR5jpdbL83Fbq 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key.pub: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4f5wg5l2hKsTeNem/V41 3 | fGnJm6gOdrj8ym3rFkEU/wT8RDtnSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7 4 | mCpz9Er5qLaMXJwZxzHzAahlfA0icqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBp 5 | HssPnpYGIn20ZZuNlX2BrClciHhCPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2 6 | XrHhR+1DcKJzQBSTAGnpYVaqpsARap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3b 7 | ODIRe1AuTyHceAbewn8b462yEWKARdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy 8 | 7wIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/flock/README.md: -------------------------------------------------------------------------------- 1 | # Go flock(2) sync.Locker 2 | 3 | This is a simple implementation of the `sync.Locker` interface backed by the 4 | **[flock(2)](http://linux.die.net/man/2/flock)** syscall. 5 | 6 | I wouldn't recommend using this in production, but it can be handy if you need a 7 | quick inter process lock to prevent concurrent access to shared resources in 8 | tests. 9 | 10 | ## Usage 11 | 12 | ```go 13 | l := flock.NewPath("/tmp/mylock.lock") 14 | l.Lock() 15 | defer l.Unlock() 16 | ``` 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/flock/flock.go: -------------------------------------------------------------------------------- 1 | package flock 2 | 3 | import ( 4 | "os" 5 | "syscall" 6 | ) 7 | 8 | // Lock is an implementation of the sync.Locker interface that is backed by a 9 | // file flock(2). 10 | type Lock struct { 11 | f *os.File 12 | fd uintptr 13 | } 14 | 15 | // New returns a new Lock instance using the provided file as the backend. 16 | func New(f *os.File) *Lock { 17 | return &Lock{ 18 | f: f, 19 | fd: f.Fd(), 20 | } 21 | } 22 | 23 | // NewPath first creates the file at the given path, then returns a new Lock 24 | // instance backed by the file. 25 | func NewPath(path string) (*Lock, error) { 26 | f, err := os.Create(path) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | return New(f), nil 32 | } 33 | 34 | // Lock aquires a lock on the file using flock(2). Lock will block if the file 35 | // was previously locked. 36 | func (l *Lock) Lock() { 37 | if err := syscall.Flock(int(l.fd), syscall.LOCK_EX); err != nil { 38 | panic(err) 39 | } 40 | } 41 | 42 | // Unlock removes the lock on the file using flock(2). 43 | func (l *Lock) Unlock() { 44 | if err := syscall.Flock(int(l.fd), syscall.LOCK_UN); err != nil { 45 | panic(err) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/flock/flock_test.go: -------------------------------------------------------------------------------- 1 | package flock 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | func TestLock(t *testing.T) { 9 | l1 := newTestLock(t) 10 | l1.Lock() 11 | 12 | aquired := make(chan struct{}, 1) 13 | l2 := newTestLock(t) 14 | go func() { 15 | l2.Lock() 16 | aquired <- struct{}{} 17 | }() 18 | 19 | select { 20 | case <-aquired: 21 | t.Fatal("Lock should not have been aquired") 22 | case <-time.After(100 * time.Millisecond): 23 | // Timed out, which means the lock is probably working. 24 | } 25 | 26 | aquired = make(chan struct{}, 1) 27 | go func() { 28 | l2.Lock() 29 | aquired <- struct{}{} 30 | }() 31 | 32 | l1.Unlock() 33 | 34 | select { 35 | case <-aquired: 36 | case <-time.After(100 * time.Millisecond): 37 | t.Fatal("Timed out while aquiring lock") 38 | } 39 | } 40 | 41 | var testFile = "/tmp/flock.test.lock" 42 | 43 | func newTestLock(t testing.TB) *Lock { 44 | l, err := NewPath(testFile) 45 | if err != nil { 46 | t.Fatal(err) 47 | } 48 | 49 | return l 50 | } 51 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.3 5 | 6 | before_install: 7 | - go install -a -race std 8 | - go get ./... 9 | - export PATH=$HOME/gopath/bin:$PATH 10 | 11 | script: 12 | - go test -race ./... 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Eric Holmes 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/README.md: -------------------------------------------------------------------------------- 1 | # [Hookshot](https://github.com/ejholmes/hookshot) [![Build Status](https://travis-ci.org/ejholmes/hookshot.svg?branch=master)](https://travis-ci.org/ejholmes/hookshot) 2 | 3 | [Godoc](http://godoc.org/github.com/ejholmes/hookshot) 4 | 5 | Hookshot is a Go http router that de-multiplexes and authorizes GitHub Webhooks. 6 | 7 | 8 | ## Usage 9 | 10 | ```go 11 | r := hookshot.NewRouter() 12 | 13 | r.Handle("deployment_status", DeploymentStatusHandler) 14 | r.Handle("deployment", DeploymentHandler) 15 | ``` 16 | 17 | To automatically verify the `X-Hub-Signature`: 18 | 19 | 20 | ```go 21 | r.Handle("deployment", hookshot.Authorize(DeploymentHandler, "secret")) 22 | ``` 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/events/events.go: -------------------------------------------------------------------------------- 1 | // Package events containers types representing GitHub webhook payloads. This 2 | // package is autogenerated from https://github.com/github/developer.github.com/tree/master/lib/webhooks 3 | package events 4 | 5 | //go:generate ./generate 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/events/generate: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | events=" 4 | commit_comment 5 | create 6 | delete 7 | deployment 8 | deployment_status 9 | fork 10 | gollum 11 | issue_comment 12 | issues 13 | member 14 | membership 15 | page_build 16 | ping 17 | public 18 | pull_request 19 | pull_request_review_comment 20 | push 21 | release 22 | repository 23 | status 24 | team_add 25 | watch 26 | " 27 | 28 | for event in $events; do 29 | name=$(ruby -r 'active_support' -r 'active_support/core_ext' -e "print '${event}'.camelize") 30 | curl -Ls https://raw.githubusercontent.com/github/developer.github.com/master/lib/webhooks/${event}.payload.json | gojson -pkg=events -name=${name} > ${event}.go 31 | done 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Eric Holmes. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package hookshot_test 6 | 7 | import ( 8 | "net/http" 9 | 10 | "github.com/ejholmes/hookshot" 11 | ) 12 | 13 | func HandlePing(w http.ResponseWriter, r *http.Request) { 14 | w.WriteHeader(200) 15 | w.Write([]byte(`Pong`)) 16 | } 17 | 18 | func Example() { 19 | r := hookshot.NewRouter() 20 | r.HandleFunc("ping", HandlePing) 21 | 22 | http.ListenAndServe(":8080", r) 23 | } 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/ejholmes/hookshot/hooker/hooker_test.go: -------------------------------------------------------------------------------- 1 | package hooker 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "net/http" 7 | "net/http/httptest" 8 | "testing" 9 | 10 | "github.com/ejholmes/hookshot" 11 | ) 12 | 13 | func TestHooker(t *testing.T) { 14 | h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 | raw, err := ioutil.ReadAll(r.Body) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | if got, want := string(raw), `{"Data":"foo"}`+"\n"; got != want { 21 | t.Fatalf("Body => %s; want %s", got, want) 22 | } 23 | 24 | io.WriteString(w, "ok\n") 25 | }) 26 | s := httptest.NewServer(hookshot.Authorize(h, "secret")) 27 | defer s.Close() 28 | 29 | c := NewClient(nil) 30 | c.Secret = "secret" 31 | c.URL = s.URL 32 | 33 | body := struct { 34 | Data string 35 | }{ 36 | Data: "foo", 37 | } 38 | resp, err := c.Trigger("ping", &body) 39 | if err != nil { 40 | t.Fatal(err) 41 | } 42 | 43 | raw, err := ioutil.ReadAll(resp.Body) 44 | if err != nil { 45 | t.Fatal(err) 46 | } 47 | 48 | if got, want := string(raw), "ok\n"; got != want { 49 | t.Fatalf("Response => %s; want %s", got, want) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .DS_Store? 3 | ._* 4 | .Spotlight-V100 5 | .Trashes 6 | Icon? 7 | ehthumbs.db 8 | Thumbs.db 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - tip 8 | 9 | before_script: 10 | - mysql -e 'create database gotest;' 11 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of Go-MySQL-Driver authors for copyright purposes. 2 | 3 | # If you are submitting a patch, please add your name or the name of the 4 | # organization which holds the copyright to this list in alphabetical order. 5 | 6 | # Names should be added to this file as 7 | # Name 8 | # The email address is not required for organizations. 9 | # Please keep the list sorted. 10 | 11 | 12 | # Individual Persons 13 | 14 | Aaron Hopkins 15 | Arne Hormann 16 | Carlos Nieto 17 | Chris Moos 18 | DisposaBoy 19 | Frederick Mayle 20 | Gustavo Kristic 21 | Hanno Braun 22 | Henri Yandell 23 | INADA Naoki 24 | James Harr 25 | Jian Zhen 26 | Julien Schmidt 27 | Kamil Dziedzic 28 | Leonardo YongUk Kim 29 | Lucas Liu 30 | Luke Scott 31 | Michael Woolnough 32 | Nicola Peduzzi 33 | Runrioter Wung 34 | Xiaobing Jiang 35 | Xiuming Chen 36 | 37 | # Organizations 38 | 39 | Barracuda Networks, Inc. 40 | Google Inc. 41 | Stripe Inc. 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | ## Reporting Issues 4 | 5 | Before creating a new Issue, please check first if a similar Issue [already exists](https://github.com/go-sql-driver/mysql/issues?state=open) or was [recently closed](https://github.com/go-sql-driver/mysql/issues?direction=desc&page=1&sort=updated&state=closed). 6 | 7 | Please provide the following minimum information: 8 | * Your Go-MySQL-Driver version (or git SHA) 9 | * Your Go version (run `go version` in your console) 10 | * A detailed issue description 11 | * Error Log if present 12 | * If possible, a short example 13 | 14 | 15 | ## Contributing Code 16 | 17 | By contributing to this project, you share your code under the Mozilla Public License 2, as specified in the LICENSE file. 18 | Don't forget to add yourself to the AUTHORS file. 19 | 20 | ### Pull Requests Checklist 21 | 22 | Please check the following points before submitting your pull request: 23 | - [x] Code compiles correctly 24 | - [x] Created tests, if possible 25 | - [x] All tests pass 26 | - [x] Extended the README / documentation, if necessary 27 | - [x] Added yourself to the AUTHORS file 28 | 29 | ### Code Review 30 | 31 | Everyone is invited to review and comment on pull requests. 32 | If it looks fine to you, comment with "LGTM" (Looks good to me). 33 | 34 | If changes are required, notice the reviewers with "PTAL" (Please take another look) after committing the fixes. 35 | 36 | Before merging the Pull Request, at least one [team member](https://github.com/go-sql-driver?tab=members) must have commented with "LGTM". 37 | 38 | ## Development Ideas 39 | 40 | If you are looking for ideas for code contributions, please check our [Development Ideas](https://github.com/go-sql-driver/mysql/wiki/Development-Ideas) Wiki page. 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/appengine.go: -------------------------------------------------------------------------------- 1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package 2 | // 3 | // Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. 4 | // 5 | // This Source Code Form is subject to the terms of the Mozilla Public 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | // You can obtain one at http://mozilla.org/MPL/2.0/. 8 | 9 | // +build appengine 10 | 11 | package mysql 12 | 13 | import ( 14 | "appengine/cloudsql" 15 | ) 16 | 17 | func init() { 18 | RegisterDial("cloudsql", cloudsql.Dial) 19 | } 20 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/errors_test.go: -------------------------------------------------------------------------------- 1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package 2 | // 3 | // Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. 4 | // 5 | // This Source Code Form is subject to the terms of the Mozilla Public 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | // You can obtain one at http://mozilla.org/MPL/2.0/. 8 | 9 | package mysql 10 | 11 | import ( 12 | "bytes" 13 | "log" 14 | "testing" 15 | ) 16 | 17 | func TestErrorsSetLogger(t *testing.T) { 18 | previous := errLog 19 | defer func() { 20 | errLog = previous 21 | }() 22 | 23 | // set up logger 24 | const expected = "prefix: test\n" 25 | buffer := bytes.NewBuffer(make([]byte, 0, 64)) 26 | logger := log.New(buffer, "prefix: ", 0) 27 | 28 | // print 29 | SetLogger(logger) 30 | errLog.Print("test") 31 | 32 | // check result 33 | if actual := buffer.String(); actual != expected { 34 | t.Errorf("expected %q, got %q", expected, actual) 35 | } 36 | } 37 | 38 | func TestErrorsStrictIgnoreNotes(t *testing.T) { 39 | runTests(t, dsn+"&sql_notes=false", func(dbt *DBTest) { 40 | dbt.mustExec("DROP TABLE IF EXISTS does_not_exist") 41 | }) 42 | } 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/result.go: -------------------------------------------------------------------------------- 1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package 2 | // 3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. 4 | // 5 | // This Source Code Form is subject to the terms of the Mozilla Public 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | // You can obtain one at http://mozilla.org/MPL/2.0/. 8 | 9 | package mysql 10 | 11 | type mysqlResult struct { 12 | affectedRows int64 13 | insertId int64 14 | } 15 | 16 | func (res *mysqlResult) LastInsertId() (int64, error) { 17 | return res.insertId, nil 18 | } 19 | 20 | func (res *mysqlResult) RowsAffected() (int64, error) { 21 | return res.affectedRows, nil 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/go-sql-driver/mysql/transaction.go: -------------------------------------------------------------------------------- 1 | // Go MySQL Driver - A MySQL-Driver for Go's database/sql package 2 | // 3 | // Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. 4 | // 5 | // This Source Code Form is subject to the terms of the Mozilla Public 6 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | // You can obtain one at http://mozilla.org/MPL/2.0/. 8 | 9 | package mysql 10 | 11 | type mysqlTx struct { 12 | mc *mysqlConn 13 | } 14 | 15 | func (tx *mysqlTx) Commit() (err error) { 16 | if tx.mc == nil || tx.mc.netConn == nil { 17 | return ErrInvalidConn 18 | } 19 | err = tx.mc.exec("COMMIT") 20 | tx.mc = nil 21 | return 22 | } 23 | 24 | func (tx *mysqlTx) Rollback() (err error) { 25 | if tx.mc == nil || tx.mc.netConn == nil { 26 | return ErrInvalidConn 27 | } 28 | err = tx.mc.exec("ROLLBACK") 29 | tx.mc = nil 30 | return 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/.gitignore: -------------------------------------------------------------------------------- 1 | gocql-fuzz 2 | fuzz-corpus 3 | fuzz-work 4 | gocql.test -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: false 4 | 5 | cache: 6 | directories: 7 | - $HOME/.ccm/repository 8 | 9 | matrix: 10 | fast_finish: true 11 | 12 | env: 13 | global: 14 | - GOMAXPROCS=2 15 | matrix: 16 | - CASS=1.2.19 AUTH=false 17 | - CASS=2.0.14 AUTH=false 18 | - CASS=2.1.5 AUTH=false 19 | - CASS=2.1.5 AUTH=true 20 | 21 | go: 22 | - 1.3 23 | - 1.4 24 | 25 | install: 26 | - pip install --user cql PyYAML six 27 | - go get golang.org/x/tools/cmd/vet 28 | - go get golang.org/x/tools/cmd/cover 29 | - git clone https://github.com/pcmanus/ccm.git 30 | - pushd ccm 31 | - ./setup.py install --user 32 | - popd 33 | - go get . 34 | 35 | script: 36 | - set -e 37 | - go test -v -tags unit 38 | - PATH=$PATH:$HOME/.local/bin bash -x integration.sh $CASS $AUTH 39 | - go vet . 40 | 41 | notifications: 42 | - email: false 43 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source file refers to The gocql Authors for copyright purposes. 2 | 3 | Christoph Hack 4 | Jonathan Rudenberg 5 | Thorsten von Eicken 6 | Matt Robenolt 7 | Phillip Couto 8 | Niklas Korz 9 | Nimi Wariboko Jr 10 | Ghais Issa 11 | Sasha Klizhentas 12 | Konstantin Cherkasov 13 | Ben Hood <0x6e6562@gmail.com> 14 | Pete Hopkins 15 | Chris Bannister 16 | Maxim Bublis 17 | Alex Zorin 18 | Kasper Middelboe Petersen 19 | Harpreet Sawhney 20 | Charlie Andrews 21 | Stanislavs Koikovs 22 | Dan Forest 23 | Miguel Serrano 24 | Stefan Radomski 25 | Josh Wright 26 | Jacob Rhoden 27 | Ben Frye 28 | Fred McCann 29 | Dan Simmons 30 | Muir Manders 31 | Sankar P 32 | Julien Da Silva 33 | Dan Kennedy 34 | Nick Dhupia 35 | Yasuharu Goto 36 | Jeremy Schlatter 37 | Matthias Kadenbach 38 | Dean Elbaz 39 | Mike Berman 40 | Dmitriy Fedorenko 41 | Zach Marcantel 42 | James Maloney 43 | Ashwin Purohit 44 | Dan Kinder 45 | Oliver Beattie 46 | Justin Corpron 47 | Miles Delahunty 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The gocql Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/cass1batch_test.go: -------------------------------------------------------------------------------- 1 | // +build all integration 2 | 3 | package gocql 4 | 5 | import ( 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestProto1BatchInsert(t *testing.T) { 11 | session := createSession(t) 12 | if err := session.Query("CREATE TABLE large (id int primary key)").Exec(); err != nil { 13 | t.Fatal("create table:", err) 14 | } 15 | defer session.Close() 16 | 17 | begin := "BEGIN BATCH" 18 | end := "APPLY BATCH" 19 | query := "INSERT INTO large (id) VALUES (?)" 20 | fullQuery := strings.Join([]string{begin, query, end}, "\n") 21 | args := []interface{}{5} 22 | if err := session.Query(fullQuery, args...).Consistency(Quorum).Exec(); err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | } 27 | 28 | func TestShouldPrepareFunction(t *testing.T) { 29 | var shouldPrepareTests = []struct { 30 | Stmt string 31 | Result bool 32 | }{ 33 | {` 34 | BEGIN BATCH 35 | INSERT INTO users (userID, password) 36 | VALUES ('smith', 'secret') 37 | APPLY BATCH 38 | ; 39 | `, true}, 40 | {`INSERT INTO users (userID, password, name) VALUES ('user2', 'ch@ngem3b', 'second user')`, true}, 41 | {`BEGIN COUNTER BATCH UPDATE stats SET views = views + 1 WHERE pageid = 1 APPLY BATCH`, true}, 42 | {`delete name from users where userID = 'smith';`, true}, 43 | {` UPDATE users SET password = 'secret' WHERE userID = 'smith' `, true}, 44 | {`CREATE TABLE users ( 45 | user_name varchar PRIMARY KEY, 46 | password varchar, 47 | gender varchar, 48 | session_token varchar, 49 | state varchar, 50 | birth_year bigint 51 | );`, false}, 52 | } 53 | 54 | for _, test := range shouldPrepareTests { 55 | q := &Query{stmt: test.Stmt} 56 | if got := q.shouldPrepare(); got != test.Result { 57 | t.Fatalf("%q: got %v, expected %v\n", test.Stmt, got, test.Result) 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/compressor.go: -------------------------------------------------------------------------------- 1 | package gocql 2 | 3 | import ( 4 | "github.com/golang/snappy/snappy" 5 | ) 6 | 7 | type Compressor interface { 8 | Name() string 9 | Encode(data []byte) ([]byte, error) 10 | Decode(data []byte) ([]byte, error) 11 | } 12 | 13 | // SnappyCompressor implements the Compressor interface and can be used to 14 | // compress incoming and outgoing frames. The snappy compression algorithm 15 | // aims for very high speeds and reasonable compression. 16 | type SnappyCompressor struct{} 17 | 18 | func (s SnappyCompressor) Name() string { 19 | return "snappy" 20 | } 21 | 22 | func (s SnappyCompressor) Encode(data []byte) ([]byte, error) { 23 | return snappy.Encode(nil, data) 24 | } 25 | 26 | func (s SnappyCompressor) Decode(data []byte) ([]byte, error) { 27 | return snappy.Decode(nil, data) 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/compressor_test.go: -------------------------------------------------------------------------------- 1 | // +build all unit 2 | 3 | package gocql 4 | 5 | import ( 6 | "bytes" 7 | "github.com/golang/snappy/snappy" 8 | "testing" 9 | ) 10 | 11 | func TestSnappyCompressor(t *testing.T) { 12 | c := SnappyCompressor{} 13 | if c.Name() != "snappy" { 14 | t.Fatalf("expected name to be 'snappy', got %v", c.Name()) 15 | } 16 | 17 | str := "My Test String" 18 | //Test Encoding 19 | if expected, err := snappy.Encode(nil, []byte(str)); err != nil { 20 | t.Fatalf("failed to encode '%v' with error %v", str, err) 21 | } else if res, err := c.Encode([]byte(str)); err != nil { 22 | t.Fatalf("failed to encode '%v' with error %v", str, err) 23 | } else if bytes.Compare(expected, res) != 0 { 24 | t.Fatal("failed to match the expected encoded value with the result encoded value.") 25 | } 26 | 27 | val, err := c.Encode([]byte(str)) 28 | if err != nil { 29 | t.Fatalf("failed to encode '%v' with error '%v'", str, err) 30 | } 31 | 32 | //Test Decoding 33 | if expected, err := snappy.Decode(nil, val); err != nil { 34 | t.Fatalf("failed to decode '%v' with error %v", val, err) 35 | } else if res, err := c.Decode(val); err != nil { 36 | t.Fatalf("failed to decode '%v' with error %v", val, err) 37 | } else if bytes.Compare(expected, res) != 0 { 38 | t.Fatal("failed to match the expected decoded value with the result decoded value.") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2015 The gocql Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package gocql implements a fast and robust Cassandra driver for the 6 | // Go programming language. 7 | package gocql 8 | 9 | // TODO(tux21b): write more docs. 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/errors.go: -------------------------------------------------------------------------------- 1 | package gocql 2 | 3 | import "fmt" 4 | 5 | const ( 6 | errServer = 0x0000 7 | errProtocol = 0x000A 8 | errCredentials = 0x0100 9 | errUnavailable = 0x1000 10 | errOverloaded = 0x1001 11 | errBootstrapping = 0x1002 12 | errTruncate = 0x1003 13 | errWriteTimeout = 0x1100 14 | errReadTimeout = 0x1200 15 | errSyntax = 0x2000 16 | errUnauthorized = 0x2100 17 | errInvalid = 0x2200 18 | errConfig = 0x2300 19 | errAlreadyExists = 0x2400 20 | errUnprepared = 0x2500 21 | ) 22 | 23 | type RequestError interface { 24 | Code() int 25 | Message() string 26 | Error() string 27 | } 28 | 29 | type errorFrame struct { 30 | frameHeader 31 | 32 | code int 33 | message string 34 | } 35 | 36 | func (e errorFrame) Code() int { 37 | return e.code 38 | } 39 | 40 | func (e errorFrame) Message() string { 41 | return e.message 42 | } 43 | 44 | func (e errorFrame) Error() string { 45 | return e.Message() 46 | } 47 | 48 | func (e errorFrame) String() string { 49 | return fmt.Sprintf("[error code=%x message=%q]", e.code, e.message) 50 | } 51 | 52 | type RequestErrUnavailable struct { 53 | errorFrame 54 | Consistency Consistency 55 | Required int 56 | Alive int 57 | } 58 | 59 | func (e *RequestErrUnavailable) String() string { 60 | return fmt.Sprintf("[request_error_unavailable consistency=%s required=%d alive=%d]", e.Consistency, e.Required, e.Alive) 61 | } 62 | 63 | type RequestErrWriteTimeout struct { 64 | errorFrame 65 | Consistency Consistency 66 | Received int 67 | BlockFor int 68 | WriteType string 69 | } 70 | 71 | type RequestErrReadTimeout struct { 72 | errorFrame 73 | Consistency Consistency 74 | Received int 75 | BlockFor int 76 | DataPresent byte 77 | } 78 | 79 | type RequestErrAlreadyExists struct { 80 | errorFrame 81 | Keyspace string 82 | Table string 83 | } 84 | 85 | type RequestErrUnprepared struct { 86 | errorFrame 87 | StatementId []byte 88 | } 89 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/errors_test.go: -------------------------------------------------------------------------------- 1 | // +build all integration 2 | 3 | package gocql 4 | 5 | import ( 6 | "testing" 7 | ) 8 | 9 | func TestErrorsParse(t *testing.T) { 10 | session := createSession(t) 11 | defer session.Close() 12 | 13 | if err := createTable(session, `CREATE TABLE errors_parse (id int primary key)`); err != nil { 14 | t.Fatal("create:", err) 15 | } 16 | 17 | if err := createTable(session, `CREATE TABLE errors_parse (id int primary key)`); err == nil { 18 | t.Fatal("Should have gotten already exists error from cassandra server.") 19 | } else { 20 | switch e := err.(type) { 21 | case *RequestErrAlreadyExists: 22 | if e.Table != "errors_parse" { 23 | t.Fatal("Failed to parse error response from cassandra for ErrAlreadyExists.") 24 | } 25 | default: 26 | t.Fatal("Failed to parse error response from cassandra for ErrAlreadyExists.") 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/fuzz.go: -------------------------------------------------------------------------------- 1 | // +build gofuzz 2 | 3 | package gocql 4 | 5 | import "bytes" 6 | 7 | func Fuzz(data []byte) int { 8 | var bw bytes.Buffer 9 | 10 | r := bytes.NewReader(data) 11 | 12 | head, err := readHeader(r, make([]byte, 9)) 13 | if err != nil { 14 | return 0 15 | } 16 | 17 | framer := newFramer(r, &bw, nil, 3) 18 | err = framer.readFrame(&head) 19 | if err != nil { 20 | return 0 21 | } 22 | 23 | frame, err := framer.parseFrame() 24 | if err != nil { 25 | return 0 26 | } 27 | 28 | if frame != nil { 29 | return 1 30 | } 31 | 32 | return 2 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/.keystore -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/.truststore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/.truststore -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDLzCCAhegAwIBAgIJAIKbAXgemwsjMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV 3 | BAMTCWNhc3NhbmRyYTAeFw0xNDA5MTkyMTE4MTNaFw0yNDA5MTYyMTE4MTNaMBQx 4 | EjAQBgNVBAMTCWNhc3NhbmRyYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC 5 | ggEBAL5fX0l1WDNa+mO1krxw7k8lfUQn+Ec4L3Mqv6IstGoNdCPq4YRA+SXRD5YC 6 | k/UXrFBWh9Hbs849GiuTYMPdj9HDLYz40RaQjM9GbieS23iy3UStQ0tKhxaaG6FN 7 | 6XBypXFKCTsanu0TkEoDGhAkSzAMcCAC3gkFBzMrZ5qt4HEzjY9rasZ2gthN+xop 8 | nq3t4dDkE8HGaiFJcFvqTor7xmrnAaPjrPzUpvOF/ObIC09omwg/KXdPRx4DKPon 9 | gCMKEE3ckebKnJvbsRX3WO8H5nTHBYZ6v1JxLZz5pqmV+P0NGxldCARM0gCQUBz5 10 | wjMJkD/3e1ETC+q6uwfnAG0hlD8CAwEAAaOBgzCBgDAdBgNVHQ4EFgQUjHzn0nYF 11 | iXEaI1vUWbRR4lwKXOgwRAYDVR0jBD0wO4AUjHzn0nYFiXEaI1vUWbRR4lwKXOih 12 | GKQWMBQxEjAQBgNVBAMTCWNhc3NhbmRyYYIJAIKbAXgemwsjMAwGA1UdEwQFMAMB 13 | Af8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBCYDdIhtf/Y12Et947 14 | am1B8TzSX+/iQ1V1J3JtvgD5F4fvNjfArat/I3D277WREUTAc76o16BCp2OBGqzO 15 | zf9MvZPkjkAUoyU0TtPUEHyqxq4gZxbWKugIZGYkmQ1hCvSIgA5UnjRL3dylMmZb 16 | Y33JJA2QY63FZwnhmWsM8FYZwh+8MzVCQx3mgXC/k/jS6OuYyIT/KjxQHHjyr5ZS 17 | zAAQln1IcZycLfh1w5MtCFahCIethFcVDnWUWYPcPGDGgMJW7WBpNZdHbLxYY8cI 18 | eCc3Hcrbdc/CG5CaLJeqUidBayjnlUIO/NNgglkJ1KhQzkM6bd+37e0AX1hLIqx7 19 | gIZR 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/ca.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | Proc-Type: 4,ENCRYPTED 3 | DEK-Info: DES-EDE3-CBC,54C8072C0FF3B3A3 4 | 5 | 27eijmHdgB+s3beNPmU0+iz+muxMD0BVvWkDzyec/uawMv/Cn4c3mYXOcsFxS3BL 6 | +qLT9MEttOmjqhHSaVrDYOPKoJIMpn+bVeKiR08V89icO36shEPy1feGqanagKtw 7 | ecgzFDBTA8ZbqjAhftXlhTwxADebvNms/2aDh5Aw04vIcbo8nQ/8z1Wz8O7Firsn 8 | kaseSTMTC6lxc+pa2V1X6mN0/2UpDi55bZbx1Z/mQ3+1CsdHOx0p7m/KY2m3ysov 9 | XluaC0sqmzHkcwNgDhUs3Jh+apE33vXzLGU+W4BDOwrYJiL6KpspZW/mJj3OEx8B 10 | 8xdAZU3a/ei8NUA/lDStGmcYX+dOysExwJ6GMrCBm9iufZiefDQCQ8yRqWnr6Zop 11 | lsFd+CqHNWYxfWDI1pSUBw3bsgIjevI0f0B7PxkFEF0DmIhCgB324/uqToRzGsOF 12 | 4MSVg6cSK7Sjo/u3r8r75A3aUAcY8NbR3peiZfAPMsTiUcfp4DoU+MJTqkX5PyQq 13 | FNxHOJoARZqjjQ2IhZiUQWfIINHvZ8F9G2K7VaES8A0EATyUghqaRyeLbyI3IYdW 14 | pGZBzrpGtdFlk9AVetHDDlY+gQiurtYhxOsxvlxJJuTj8FV+A5NWSElfPele0OiR 15 | iprE3xkFSk3whHu5L1vnzamvdSlnBWOAE7pQD7kQA6NmcEw/tqnXK0dVdAw8RIFh 16 | 4BKgv0sNrXzBgnzE8+bKLUf1a2Byc/YKuBrI7EpSZ9/VHYvOcgmOxNxMmRS6NYd1 17 | Ly+agQn0AyvsDmSlBZBp8GCzVp6JYBMDKSXyPVN8+wjK9OQM0PZdEdXouMwPCOVN 18 | oNSjhmMtfjOsnG2SZ9tRas3p0qFdfh/N/E6Q7QHG3WD3cUIEweFV9ji1FTSRUrIa 19 | shuKug8MUfNjvDJNMsdGyf6Hi/7Iik++42Rq3ZdTy0ZVkj5snv5yBN77pr2M/J4b 20 | M+dsXjyXPO4SDW3kP/e3RnLRlWmUv1PNdOmNDdjBBUTKgVZ3ur+4HmSY1iDvhlUF 21 | /hz2tz3/XUKQwYuv3KJVlBhLrniXeES36GK+JQadIszrjwb5N4q4p6xrIdIR7XgR 22 | TJCSL1NGPLeQyjK6byWLNPRcCGrvnxWs0k0ev6trMRJL1EjsIFDCJam9szhcXkZP 23 | iYl1d7ZMKPS3cAqCjdaFRSe65cZ+qI/cqxiv122orq/jkDY7ZSA9rWywY4YnYQ7A 24 | BqvcPzC/6K0bteXqmMQkIy/84aSnEts6ecb/4s5e5xXLhHe0dchG0HkasC/Gb+v/ 25 | m9NOqACTerWvSD+Ecv9OvnBjP+GTlA1g7xTiRANLXsTJuiJomtxewXcV6kGZEMmZ 26 | QWerGtPJGGUx36WRWrMiPeBfWZoIbjYGPmOO5mYNXMTjABGGWcFnKAqWUKsFihi9 27 | pC0OpZ7A0dtc9uSm0ZmsHUc3XENMHTeeEN+qgWxVKcMzRKEcnapu/0OcHrOUHDZf 28 | qPoG4EkNnG9kPMq3HzvFPx3qbQ017yl87vAkWy/Edo+ojfHoNghRBVGCw1zt/BMN 29 | eJbFFHop+rQ87omz8WIL4K+zVf91rJ0REVAJssQVDo16O5wrMo+f+c8v2GANQks5 30 | -----END RSA PRIVATE KEY----- 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/cassandra.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEA5Zwgnt6Yc0RBDTdMYsOfh1+bT6rP9pBupeCJiHoAxrvXgIdp 3 | LvrwNVmAboIlyLNs9qSXl5OT6vBwcKTht6rawZlmm5MEOs4LgwcGIj2m239oD0mA 4 | vYaou1RtOF8PsPoblySuzJ03mH52zOMbRRshJRcCwBrF+3bDi5PXxYUUClykEucY 5 | aZj1ds14zZlaKWXxaCCX074Js2gb8qOimnNYU37thjKjWtVGA/mztOxjcbq7+2/5 6 | gmPkVUd6euR7F2vX5s87yasMMBXJ7cfW/LZyshR9x/N/ivRjcGSOD9voOkVHzbl7 7 | rsgxwVLRPjQSt3PnuomGmjbtoFpp0NTjthaFrwIDAQABAoIBAQChjdjl73kUoVGk 8 | GuSEGWCFv59nzqfEtJsl23bpr+4b5s8agCxiAe5Bm1fiaXBsZtKkN+rxm8TX6ZUz 9 | rM+ki3KgBW9Mx4SSW6d96dNHBFoC1wJAv1b2A2l1ZVHz9+7ydwgysHzNO1GC2nh8 10 | cM8fMJeBoU8uG6hx5n5wFvYa5CfVoUQh8+Oq0b+mVxEFKHmRPnWp9/jPzL5eBIdr 11 | ulbDt9S3dKJtouHgHBUNdkq/7Ex3QeHrUOahX6Y4eX1rzLnfLYY+0J4EA2PCKvgQ 12 | bfKCxVnnzL6ywviH8eS3ql6OvTfnbK9kCRw7WxX9CC50qKj3EmwC/51MPhWohWlq 13 | jw3qf38BAoGBAPPNyb3vUiyUqoErZxxIPFc2ob3vCjj06cvi7uKpOgrkdgC3iBhz 14 | aCFQ28r7LrxLAHaKvNvwp71Lc7WYo8WWkLI1DVn0dx+GiQYW3DbNcwZOS40ZQz5L 15 | zsjEcG4+cnZmuqGZBMNvQ+xUjkuucxvxPWKpEKM18GfDjgEkKbmDr+uNAoGBAPEY 16 | kVSfSZGtP0MoXIfRkrxBlhvCj9m+p60P37pyHrJBrlrwvxB7x3Oz8S70D6kV8s2g 17 | vVHgOS3VPj17VaQG8a3jBLKjzp5JLe34G8D1Ny8GqDc2wzOBtZySpJbifXuSUSPk 18 | cqF7yiu1cD/wRPlwyWxBX9ZbaxvxnIUwLLd3ygkrAoGBAKQaw42uVkCdvPr/DQOT 19 | d9I4erxO9zGJYQmU8bjtsZz9VJR89QWIQPIT7C3/zuB9F42zKxZcMXwQGo2EddAc 20 | 3b6mSRtgmwJEW10W7BmTRrZa4y3RcFqxSjoHR6pdLEyYL01woy0taqnb7H/yp5aK 21 | VghfxkwllXEyxxXrko5FnpdNAoGBANeJLBunz2BxrnW+doJhZDnytFya4nk6TbKU 22 | 12FaNoEL4PCh+12kGtogSwS74eg6m/citT2mI9gKpHrYcOaT4qmeo4uEj+nH6Eyv 23 | Gzi0wCHFZMr/pSC92/teyc+uKZo4Y1ugFq6w+Tt8GB7BERiisR+bji8XSTkRFemn 24 | +MIIUFFDAoGAM8Va2Q5aTUkfg2mYlNLqT2tUAXVEhbmzjPA6laSo25PQEYWmX7vj 25 | hiU0DPCDJQ/PlPI23xYtDDLNk83Zbx+Oj29GO5pawJY9NvFI8n60EFXfLbP1nEdG 26 | j077QZNZOKfcgJirWi3+RrHSAK4tFftCe7rkV8ZmlMRBY3SDxzKOGcc= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/testdata/pki/gocql.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEArun6nv3iaYUdCA81aLxje5JQf3NQ/EJDNQazXJ4nHhYFaeyI 3 | 1ZxP7+gTaXq1s39mbRQALtavW/8skJGmEQdyXrA3wG3/e3Yr/t5M0o3OQzsaxB3e 4 | ttgmCCWJWaFLlKNXnhlGKG6XEXzmt0GWj0LdZtqG0lPd2PUgzSSLD6vfxBCyZCAd 5 | 4A/0LfbKlL6DrD6oSne2CJc6fnvgPqtoz+72oY6/7L4G0a1s7U810QSXCDOxZVth 6 | Mo1L8DA1S4trBvIacoxpvfOyxKSkcEXjZ6J6ny7LKC2faAPxx9lPg8k9jDQECjsT 7 | h5Lh9+N5fqvAJbHlOAlEPjHfEtTcew41v+4lXwIDAQABAoIBAQCCP9XSwzfwX6Fo 8 | uPqKjY5/HEs5PQPXdPha6ixyEYsLilZptCuI9adI/MZHy4q2qW36V+Ry/IcEuJXU 9 | 6cCB+cue2xYJA2A17Z+BYMRQHiy0P7UEyUFpYrefZWRMDCIeAyxhnGxz+zYfXaTo 10 | Xbzh3WbFCoFO6gjPYGoWmNm8x74PXyunNaMa/gWFECX5MMBXoOk5xSFGbHzI2Cds 11 | iT7sdCQJVbBs7yidYwNqPWQuOwrskFinPIFSc7bZ0Sx9wO3XTIrQFCE94v/AN6yR 12 | 9Q37ida54g5tgtoeg/5EGsUM++i4wqJVoT3tWUHv1jBozO4Lm65uWR/1HcrusVnr 13 | x0TM9SaBAoGBAOMeaZdUrCJXnIiSoqCGDvZmylTAeOo6n2RAiviOYxVB4GP/SSjh 14 | 8VeddFhYT1GCmZ+YjIXnRWK+dSqVukzCuf5xW5mWY7PDNGZe2P6O78lXnY4cb8Nc 15 | Uo9/S2aPnNmNHL2TYVBYUiZj+t2azIQEFvRth4Vu/AHRUG41/USxpwm/AoGBAMUo 16 | GX0xgSFAVpHnTLdzWrHNRrzHgYN8ywPKFgNOASvdgW0BFoqXEvVGc1Ak6uW82m1/ 17 | L9ChOzWjCY7CoT+LPmdUVyGT9/UAPtWeLfo8Owl4tG91jQjePmJFvLoXErryCFRt 18 | SOOvCsTTTq2gN3PREHxY3dj2kJqaCBLCEzx3cYxhAoGBAIUxdrc6/t/9BV3KsPj2 19 | 5Zt3WL0vSzoCOyut9lIiHtV+lrvOIPeK2eCKBIsy7wFcV/+SlQaKRNTN4SSiPml5 20 | 4V3o2NFPsxTfK8HFafiPluw7J7kJ0Dl/0SM6gduZ6WBkMzCyV+WohjTheWOwvrPF 21 | OjkKaunD1qKyQDsCCo/Yp589AoGAdKgnfNZf68bf8nEECcBtt6sY4fbCgYTDszhO 22 | EiKDuurT/CWaquJ9SzgmXxOZEdrO+9838aCVIkWYECrFso23nPhgnfOp0gQVKdzw 23 | o5Ij9JTBXvoVO1wVWZyd8RZZ9Nflad9IM8CNBK1rbnzQkuzvbkQ+8HPkWDYv9Ll1 24 | HGAohcECgYBQeirIumumj1B17WD/KmNe0U0qCHHp+oSW4W2r7pjlEVZzeQmggX4O 25 | anbEngyQaZKeUiUOj9snBDmzLv7S+j5p7Us4d1fbp70sCKuK6tcAnROU8gK8IGiI 26 | I01ypD8Z1Mb556qek56eRWlr71sy6wI1lbQa856cUBvePajUOKsKsw== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/topology.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The gocql Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package gocql 6 | 7 | import ( 8 | "sync" 9 | "sync/atomic" 10 | ) 11 | 12 | type Node interface { 13 | Pick(qry *Query) *Conn 14 | Close() 15 | } 16 | 17 | type RoundRobin struct { 18 | pool []Node 19 | pos uint32 20 | mu sync.RWMutex 21 | } 22 | 23 | func NewRoundRobin() *RoundRobin { 24 | return &RoundRobin{} 25 | } 26 | 27 | func (r *RoundRobin) AddNode(node Node) { 28 | r.mu.Lock() 29 | r.pool = append(r.pool, node) 30 | r.mu.Unlock() 31 | } 32 | 33 | func (r *RoundRobin) RemoveNode(node Node) { 34 | r.mu.Lock() 35 | n := len(r.pool) 36 | for i := 0; i < n; i++ { 37 | if r.pool[i] == node { 38 | r.pool[i], r.pool[n-1] = r.pool[n-1], r.pool[i] 39 | r.pool = r.pool[:n-1] 40 | break 41 | } 42 | } 43 | r.mu.Unlock() 44 | } 45 | 46 | func (r *RoundRobin) Size() int { 47 | r.mu.RLock() 48 | n := len(r.pool) 49 | r.mu.RUnlock() 50 | return n 51 | } 52 | 53 | func (r *RoundRobin) Pick(qry *Query) *Conn { 54 | pos := atomic.AddUint32(&r.pos, 1) 55 | var node Node 56 | r.mu.RLock() 57 | if len(r.pool) > 0 { 58 | node = r.pool[pos%uint32(len(r.pool))] 59 | } 60 | r.mu.RUnlock() 61 | if node == nil { 62 | return nil 63 | } 64 | return node.Pick(qry) 65 | } 66 | 67 | func (r *RoundRobin) Close() { 68 | r.mu.Lock() 69 | for i := 0; i < len(r.pool); i++ { 70 | r.pool[i].Close() 71 | } 72 | r.pool = nil 73 | r.mu.Unlock() 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/topology_test.go: -------------------------------------------------------------------------------- 1 | // +build all unit 2 | 3 | package gocql 4 | 5 | import ( 6 | "testing" 7 | ) 8 | 9 | // fakeNode is used as a simple structure to test the RoundRobin API 10 | type fakeNode struct { 11 | conn *Conn 12 | closed bool 13 | } 14 | 15 | // Pick is needed to satisfy the Node interface 16 | func (n *fakeNode) Pick(qry *Query) *Conn { 17 | if n.conn == nil { 18 | n.conn = &Conn{} 19 | } 20 | return n.conn 21 | } 22 | 23 | //Close is needed to satisfy the Node interface 24 | func (n *fakeNode) Close() { 25 | n.closed = true 26 | } 27 | 28 | //TestRoundRobinAPI tests the exported methods of the RoundRobin struct 29 | //to make sure the API behaves accordingly. 30 | func TestRoundRobinAPI(t *testing.T) { 31 | node := &fakeNode{} 32 | rr := NewRoundRobin() 33 | rr.AddNode(node) 34 | 35 | if rr.Size() != 1 { 36 | t.Fatalf("expected size to be 1, got %v", rr.Size()) 37 | } 38 | 39 | if c := rr.Pick(nil); c != node.conn { 40 | t.Fatalf("expected conn %v, got %v", node.conn, c) 41 | } 42 | 43 | rr.Close() 44 | if rr.pool != nil { 45 | t.Fatalf("expected rr.pool to be nil, got %v", rr.pool) 46 | } 47 | 48 | if !node.closed { 49 | t.Fatal("expected node.closed to be true, got false") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/tuple_test.go: -------------------------------------------------------------------------------- 1 | // +build all integration 2 | 3 | package gocql 4 | 5 | import "testing" 6 | 7 | func TestTupleSimple(t *testing.T) { 8 | if *flagProto < protoVersion3 { 9 | t.Skip("tuple types are only available of proto>=3") 10 | } 11 | 12 | session := createSession(t) 13 | defer session.Close() 14 | 15 | err := createTable(session, `CREATE TABLE tuple_test( 16 | id int, 17 | coord frozen>, 18 | 19 | primary key(id))`) 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | 24 | err = session.Query("INSERT INTO tuple_test(id, coord) VALUES(?, (?, ?))", 1, 100, -100).Exec() 25 | if err != nil { 26 | t.Fatal(err) 27 | } 28 | 29 | var ( 30 | id int 31 | coord struct { 32 | x int 33 | y int 34 | } 35 | ) 36 | 37 | iter := session.Query("SELECT id, coord FROM tuple_test WHERE id=?", 1) 38 | if err := iter.Scan(&id, &coord.x, &coord.y); err != nil { 39 | t.Fatal(err) 40 | } 41 | 42 | if id != 1 { 43 | t.Errorf("expected to get id=1 got: %v", id) 44 | } 45 | if coord.x != 100 { 46 | t.Errorf("expected to get coord.x=100 got: %v", coord.x) 47 | } 48 | if coord.y != -100 { 49 | t.Errorf("expected to get coord.y=-100 got: %v", coord.y) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/website/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/website/favicon.ico -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/website/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gocql/gocql/website/gocql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remind101/tugboat/e8e18e167d6e91728119c68e6f8a9c92cb913211/Godeps/_workspace/src/github.com/gocql/gocql/website/gocql.png -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/activity.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | // ActivityService handles communication with the activity related 9 | // methods of the GitHub API. 10 | // 11 | // GitHub API docs: http://developer.github.com/v3/activity/ 12 | type ActivityService struct { 13 | client *Client 14 | } 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/git.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | // GitService handles communication with the git data related 9 | // methods of the GitHub API. 10 | // 11 | // GitHub API docs: http://developer.github.com/v3/git/ 12 | type GitService struct { 13 | client *Client 14 | } 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/git_blobs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import "fmt" 9 | 10 | // Blob represents a blob object. 11 | type Blob struct { 12 | Content *string `json:"content,omitempty"` 13 | Encoding *string `json:"encoding,omitempty"` 14 | SHA *string `json:"sha,omitempty"` 15 | Size *int `json:"size,omitempty"` 16 | URL *string `json:"url,omitempty"` 17 | } 18 | 19 | // GetBlob fetchs a blob from a repo given a SHA. 20 | // 21 | // GitHub API docs: http://developer.github.com/v3/git/blobs/#get-a-blob 22 | func (s *GitService) GetBlob(owner string, repo string, sha string) (*Blob, *Response, error) { 23 | u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha) 24 | req, err := s.client.NewRequest("GET", u, nil) 25 | if err != nil { 26 | return nil, nil, err 27 | } 28 | 29 | blob := new(Blob) 30 | resp, err := s.client.Do(req, blob) 31 | return blob, resp, err 32 | } 33 | 34 | // CreateBlob creates a blob object. 35 | // 36 | // GitHub API docs: http://developer.github.com/v3/git/blobs/#create-a-blob 37 | func (s *GitService) CreateBlob(owner string, repo string, blob *Blob) (*Blob, *Response, error) { 38 | u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo) 39 | req, err := s.client.NewRequest("POST", u, blob) 40 | if err != nil { 41 | return nil, nil, err 42 | } 43 | 44 | t := new(Blob) 45 | resp, err := s.client.Do(req, t) 46 | return t, resp, err 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/git_tags_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "encoding/json" 10 | "fmt" 11 | "net/http" 12 | "reflect" 13 | "testing" 14 | ) 15 | 16 | func TestGitService_GetTag(t *testing.T) { 17 | setup() 18 | defer teardown() 19 | 20 | mux.HandleFunc("/repos/o/r/git/tags/s", func(w http.ResponseWriter, r *http.Request) { 21 | testMethod(t, r, "GET") 22 | 23 | fmt.Fprint(w, `{"tag": "t"}`) 24 | }) 25 | 26 | tag, _, err := client.Git.GetTag("o", "r", "s") 27 | 28 | if err != nil { 29 | t.Errorf("Git.GetTag returned error: %v", err) 30 | } 31 | 32 | want := &Tag{Tag: String("t")} 33 | if !reflect.DeepEqual(tag, want) { 34 | t.Errorf("Git.GetTag returned %+v, want %+v", tag, want) 35 | } 36 | } 37 | 38 | func TestGitService_CreateTag(t *testing.T) { 39 | setup() 40 | defer teardown() 41 | 42 | input := &createTagRequest{Tag: String("t"), Object: String("s")} 43 | 44 | mux.HandleFunc("/repos/o/r/git/tags", func(w http.ResponseWriter, r *http.Request) { 45 | v := new(createTagRequest) 46 | json.NewDecoder(r.Body).Decode(v) 47 | 48 | testMethod(t, r, "POST") 49 | if !reflect.DeepEqual(v, input) { 50 | t.Errorf("Request body = %+v, want %+v", v, input) 51 | } 52 | 53 | fmt.Fprint(w, `{"tag": "t"}`) 54 | }) 55 | 56 | tag, _, err := client.Git.CreateTag("o", "r", &Tag{ 57 | Tag: input.Tag, 58 | Object: &GitObject{SHA: input.Object}, 59 | }) 60 | if err != nil { 61 | t.Errorf("Git.CreateTag returned error: %v", err) 62 | } 63 | 64 | want := &Tag{Tag: String("t")} 65 | if !reflect.DeepEqual(tag, want) { 66 | t.Errorf("Git.GetTag returned %+v, want %+v", tag, want) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/gitignore.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import "fmt" 9 | 10 | // GitignoresService provides access to the gitignore related functions in the 11 | // GitHub API. 12 | // 13 | // GitHub API docs: http://developer.github.com/v3/gitignore/ 14 | type GitignoresService struct { 15 | client *Client 16 | } 17 | 18 | // Gitignore represents a .gitignore file as returned by the GitHub API. 19 | type Gitignore struct { 20 | Name *string `json:"name,omitempty"` 21 | Source *string `json:"source,omitempty"` 22 | } 23 | 24 | func (g Gitignore) String() string { 25 | return Stringify(g) 26 | } 27 | 28 | // List all available Gitignore templates. 29 | // 30 | // http://developer.github.com/v3/gitignore/#listing-available-templates 31 | func (s GitignoresService) List() ([]string, *Response, error) { 32 | req, err := s.client.NewRequest("GET", "gitignore/templates", nil) 33 | if err != nil { 34 | return nil, nil, err 35 | } 36 | 37 | availableTemplates := new([]string) 38 | resp, err := s.client.Do(req, availableTemplates) 39 | if err != nil { 40 | return nil, resp, err 41 | } 42 | 43 | return *availableTemplates, resp, err 44 | } 45 | 46 | // Get a Gitignore by name. 47 | // 48 | // http://developer.github.com/v3/gitignore/#get-a-single-template 49 | func (s GitignoresService) Get(name string) (*Gitignore, *Response, error) { 50 | u := fmt.Sprintf("gitignore/templates/%v", name) 51 | req, err := s.client.NewRequest("GET", u, nil) 52 | if err != nil { 53 | return nil, nil, err 54 | } 55 | 56 | gitignore := new(Gitignore) 57 | resp, err := s.client.Do(req, gitignore) 58 | if err != nil { 59 | return nil, resp, err 60 | } 61 | 62 | return gitignore, resp, err 63 | } 64 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/gitignore_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "fmt" 10 | "net/http" 11 | "reflect" 12 | "testing" 13 | ) 14 | 15 | func TestGitignoresService_List(t *testing.T) { 16 | setup() 17 | defer teardown() 18 | 19 | mux.HandleFunc("/gitignore/templates", func(w http.ResponseWriter, r *http.Request) { 20 | testMethod(t, r, "GET") 21 | fmt.Fprint(w, `["C", "Go"]`) 22 | }) 23 | 24 | available, _, err := client.Gitignores.List() 25 | if err != nil { 26 | t.Errorf("Gitignores.List returned error: %v", err) 27 | } 28 | 29 | want := []string{"C", "Go"} 30 | if !reflect.DeepEqual(available, want) { 31 | t.Errorf("Gitignores.List returned %+v, want %+v", available, want) 32 | } 33 | } 34 | 35 | func TestGitignoresService_Get(t *testing.T) { 36 | setup() 37 | defer teardown() 38 | 39 | mux.HandleFunc("/gitignore/templates/name", func(w http.ResponseWriter, r *http.Request) { 40 | testMethod(t, r, "GET") 41 | fmt.Fprint(w, `{"name":"Name","source":"template source"}`) 42 | }) 43 | 44 | gitignore, _, err := client.Gitignores.Get("name") 45 | if err != nil { 46 | t.Errorf("Gitignores.List returned error: %v", err) 47 | } 48 | 49 | want := &Gitignore{Name: String("Name"), Source: String("template source")} 50 | if !reflect.DeepEqual(gitignore, want) { 51 | t.Errorf("Gitignores.Get returned %+v, want %+v", gitignore, want) 52 | } 53 | } 54 | 55 | func TestGitignoresService_Get_invalidTemplate(t *testing.T) { 56 | _, _, err := client.Gitignores.Get("%") 57 | testURLParseError(t, err) 58 | } 59 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/issues_assignees.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import "fmt" 9 | 10 | // ListAssignees fetches all available assignees (owners and collaborators) to 11 | // which issues may be assigned. 12 | // 13 | // GitHub API docs: http://developer.github.com/v3/issues/assignees/#list-assignees 14 | func (s *IssuesService) ListAssignees(owner string, repo string, opt *ListOptions) ([]User, *Response, error) { 15 | u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo) 16 | u, err := addOptions(u, opt) 17 | if err != nil { 18 | return nil, nil, err 19 | } 20 | 21 | req, err := s.client.NewRequest("GET", u, nil) 22 | if err != nil { 23 | return nil, nil, err 24 | } 25 | assignees := new([]User) 26 | resp, err := s.client.Do(req, assignees) 27 | if err != nil { 28 | return nil, resp, err 29 | } 30 | 31 | return *assignees, resp, err 32 | } 33 | 34 | // IsAssignee checks if a user is an assignee for the specified repository. 35 | // 36 | // GitHub API docs: http://developer.github.com/v3/issues/assignees/#check-assignee 37 | func (s *IssuesService) IsAssignee(owner string, repo string, user string) (bool, *Response, error) { 38 | u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user) 39 | req, err := s.client.NewRequest("GET", u, nil) 40 | if err != nil { 41 | return false, nil, err 42 | } 43 | resp, err := s.client.Do(req, nil) 44 | assignee, err := parseBoolResponse(err) 45 | return assignee, resp, err 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/repos_merging.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "fmt" 10 | ) 11 | 12 | // RepositoryMergeRequest represents a request to merge a branch in a 13 | // repository. 14 | type RepositoryMergeRequest struct { 15 | Base *string `json:"base,omitempty"` 16 | Head *string `json:"head,omitempty"` 17 | CommitMessage *string `json:"commit_message,omitempty"` 18 | } 19 | 20 | // Merge a branch in the specified repository. 21 | // 22 | // GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge 23 | func (s *RepositoriesService) Merge(owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) { 24 | u := fmt.Sprintf("repos/%v/%v/merges", owner, repo) 25 | req, err := s.client.NewRequest("POST", u, request) 26 | if err != nil { 27 | return nil, nil, err 28 | } 29 | 30 | commit := new(RepositoryCommit) 31 | resp, err := s.client.Do(req, commit) 32 | if err != nil { 33 | return nil, resp, err 34 | } 35 | 36 | return commit, resp, err 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/repos_merging_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "encoding/json" 10 | "fmt" 11 | "net/http" 12 | "reflect" 13 | "testing" 14 | ) 15 | 16 | func TestRepositoriesService_Merge(t *testing.T) { 17 | setup() 18 | defer teardown() 19 | 20 | input := &RepositoryMergeRequest{ 21 | Base: String("b"), 22 | Head: String("h"), 23 | CommitMessage: String("c"), 24 | } 25 | 26 | mux.HandleFunc("/repos/o/r/merges", func(w http.ResponseWriter, r *http.Request) { 27 | v := new(RepositoryMergeRequest) 28 | json.NewDecoder(r.Body).Decode(v) 29 | 30 | testMethod(t, r, "POST") 31 | if !reflect.DeepEqual(v, input) { 32 | t.Errorf("Request body = %+v, want %+v", v, input) 33 | } 34 | 35 | fmt.Fprint(w, `{"sha":"s"}`) 36 | }) 37 | 38 | commit, _, err := client.Repositories.Merge("o", "r", input) 39 | if err != nil { 40 | t.Errorf("Repositories.Merge returned error: %v", err) 41 | } 42 | 43 | want := &RepositoryCommit{SHA: String("s")} 44 | if !reflect.DeepEqual(commit, want) { 45 | t.Errorf("Repositories.Merge returned %+v, want %+v", commit, want) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/timestamp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "strconv" 10 | "time" 11 | ) 12 | 13 | // Timestamp represents a time that can be unmarshalled from a JSON string 14 | // formatted as either an RFC3339 or Unix timestamp. This is necessary for some 15 | // fields since the GitHub API is inconsistent in how it represents times. All 16 | // exported methods of time.Time can be called on Timestamp. 17 | type Timestamp struct { 18 | time.Time 19 | } 20 | 21 | func (t Timestamp) String() string { 22 | return t.Time.String() 23 | } 24 | 25 | // UnmarshalJSON implements the json.Unmarshaler interface. 26 | // Time is expected in RFC3339 or Unix format. 27 | func (t *Timestamp) UnmarshalJSON(data []byte) (err error) { 28 | str := string(data) 29 | i, err := strconv.ParseInt(str, 10, 64) 30 | if err == nil { 31 | (*t).Time = time.Unix(i, 0) 32 | } else { 33 | (*t).Time, err = time.Parse(`"`+time.RFC3339+`"`, str) 34 | } 35 | return 36 | } 37 | 38 | // Equal reports whether t and u are equal based on time.Equal 39 | func (t Timestamp) Equal(u Timestamp) bool { 40 | return t.Time.Equal(u.Time) 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/google/go-github/github/users_administration_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The go-github AUTHORS. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package github 7 | 8 | import ( 9 | "net/http" 10 | "testing" 11 | ) 12 | 13 | func TestUsersService_PromoteSiteAdmin(t *testing.T) { 14 | setup() 15 | defer teardown() 16 | 17 | mux.HandleFunc("/users/u/site_admin", func(w http.ResponseWriter, r *http.Request) { 18 | testMethod(t, r, "PUT") 19 | w.WriteHeader(http.StatusNoContent) 20 | }) 21 | 22 | _, err := client.Users.PromoteSiteAdmin("u") 23 | if err != nil { 24 | t.Errorf("Users.PromoteSiteAdmin returned error: %v", err) 25 | } 26 | } 27 | 28 | func TestUsersService_DemoteSiteAdmin(t *testing.T) { 29 | setup() 30 | defer teardown() 31 | 32 | mux.HandleFunc("/users/u/site_admin", func(w http.ResponseWriter, r *http.Request) { 33 | testMethod(t, r, "DELETE") 34 | w.WriteHeader(http.StatusNoContent) 35 | }) 36 | 37 | _, err := client.Users.DemoteSiteAdmin("u") 38 | if err != nil { 39 | t.Errorf("Users.DemoteSiteAdmin returned error: %v", err) 40 | } 41 | } 42 | 43 | func TestUsersService_Suspend(t *testing.T) { 44 | setup() 45 | defer teardown() 46 | 47 | mux.HandleFunc("/users/u/suspended", func(w http.ResponseWriter, r *http.Request) { 48 | testMethod(t, r, "PUT") 49 | w.WriteHeader(http.StatusNoContent) 50 | }) 51 | 52 | _, err := client.Users.Suspend("u") 53 | if err != nil { 54 | t.Errorf("Users.Suspend returned error: %v", err) 55 | } 56 | } 57 | 58 | func TestUsersService_Unsuspend(t *testing.T) { 59 | setup() 60 | defer teardown() 61 | 62 | mux.HandleFunc("/users/u/suspended", func(w http.ResponseWriter, r *http.Request) { 63 | testMethod(t, r, "DELETE") 64 | w.WriteHeader(http.StatusNoContent) 65 | }) 66 | 67 | _, err := client.Users.Unsuspend("u") 68 | if err != nil { 69 | t.Errorf("Users.Unsuspend returned error: %v", err) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/context/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.0 5 | - 1.1 6 | - 1.2 7 | - 1.3 8 | - 1.4 9 | - tip 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/context/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/context/README.md: -------------------------------------------------------------------------------- 1 | context 2 | ======= 3 | [![Build Status](https://travis-ci.org/gorilla/context.png?branch=master)](https://travis-ci.org/gorilla/context) 4 | 5 | gorilla/context is a general purpose registry for global request variables. 6 | 7 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/context 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/mux/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.0 5 | - 1.1 6 | - 1.2 7 | - tip 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/mux/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Rodrigo Moraes. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/mux/README.md: -------------------------------------------------------------------------------- 1 | mux 2 | === 3 | [![Build Status](https://travis-ci.org/gorilla/mux.png?branch=master)](https://travis-ci.org/gorilla/mux) 4 | 5 | gorilla/mux is a powerful URL router and dispatcher. 6 | 7 | Read the full documentation here: http://www.gorillatoolkit.org/pkg/mux 8 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/gorilla/mux/bench_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Gorilla Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package mux 6 | 7 | import ( 8 | "net/http" 9 | "testing" 10 | ) 11 | 12 | func BenchmarkMux(b *testing.B) { 13 | router := new(Router) 14 | handler := func(w http.ResponseWriter, r *http.Request) {} 15 | router.HandleFunc("/v1/{v1}", handler) 16 | 17 | request, _ := http.NewRequest("GET", "/v1/anything", nil) 18 | for i := 0; i < b.N; i++ { 19 | router.ServeHTTP(nil, request) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # The basics 2 | 3 | * Fork 4 | * Test 5 | * FMT 6 | * Pull Request 7 | 8 | # Using the Makefile 9 | 10 | ``` 11 | # Run all examples to see if they work. 12 | make examples 13 | ``` 14 | 15 | ``` 16 | # Format all go files, shortcut for go fmt ./... 17 | make fmt 18 | ``` 19 | 20 | ``` 21 | # Run all tests, shortcut for go test ./... 22 | make test 23 | ``` 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/Makefile: -------------------------------------------------------------------------------- 1 | EXAMPLES := $(wildcard examples/*.go) 2 | 3 | examples: */**.go 4 | for example in $(EXAMPLES); do \ 5 | go run $$example; \ 6 | done 7 | 8 | fmt: */**.go 9 | gofmt -w -l -tabs=false -tabwidth=4 */**.go *.go 10 | 11 | test: */**.go 12 | go test ./... 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/README.md: -------------------------------------------------------------------------------- 1 | A Go Lang Pusher Library 2 | ======================== 3 | 4 | So much to write, so little information to tell you right now :) 5 | 6 | 7 | ## Example 8 | 9 | ```go 10 | package main 11 | 12 | import ( 13 | "fmt" 14 | "github.com/timonv/pusher" 15 | "time" 16 | ) 17 | 18 | func main() { 19 | client := pusher.NewClient("appId", "key", "secret", false) 20 | 21 | done := make(chan bool) 22 | 23 | go func() { 24 | err := client.Publish("test", "test", "test") 25 | if err != nil { 26 | fmt.Printf("Error %s\n", err) 27 | } else { 28 | fmt.Print("Message Published!") 29 | } 30 | done <- true 31 | }() 32 | 33 | // A basic timeout to make sure we don't wait forever 34 | select { 35 | case <-done: 36 | fmt.Println("\nDone") 37 | case <-time.After(1 * time.Minute): 38 | fmt.Println("\n:-( Timeout") 39 | } 40 | } 41 | ``` 42 | 43 | 44 | ## License 45 | 46 | MIT: Timon Vonk and Josh Kalderimis http://timon-josh.mit-license.org -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/all_channels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "sort" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | client := pusher.NewClient("4115", "23ed642e81512118260e", "cd72de5494540704dcf1", false) 12 | 13 | done := make(chan bool) 14 | 15 | go func() { 16 | channels, err := client.AllChannels() 17 | if err != nil { 18 | fmt.Printf("Error %s\n", err) 19 | } else { 20 | names := []string{} 21 | for k := range channels.List { 22 | names = append(names, k) 23 | } 24 | sort.Strings(names) 25 | fmt.Println("Channel Count:", len(names)) 26 | fmt.Println(names) 27 | } 28 | done <- true 29 | }() 30 | 31 | select { 32 | case <-done: 33 | fmt.Println("Done :-)") 34 | case <-time.After(1 * time.Minute): 35 | fmt.Println("Timeout :-(") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/basic_publish.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | client := pusher.NewClient("34420", "87bdfd3a6320e83b9289", "f25dfe88fb26ebf75139", false) 11 | 12 | done := make(chan bool) 13 | 14 | go func() { 15 | err := client.Publish("test", "test", "test") 16 | if err != nil { 17 | fmt.Printf("Error %s\n", err) 18 | } else { 19 | fmt.Println("Message Published!") 20 | } 21 | done <- true 22 | }() 23 | 24 | select { 25 | case <-done: 26 | fmt.Println("Done :-)") 27 | case <-time.After(1 * time.Minute): 28 | fmt.Println("Timeout :-(") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/channel.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | client := pusher.NewClient("4115", "23ed642e81512118260e", "cd72de5494540704dcf1", false) 11 | 12 | done := make(chan bool) 13 | 14 | go func() { 15 | channel, err := client.Channel("common", nil) 16 | if err != nil { 17 | fmt.Printf("Error %s\n", err) 18 | } else { 19 | fmt.Println(channel) 20 | } 21 | done <- true 22 | }() 23 | 24 | select { 25 | case <-done: 26 | fmt.Println("Done :-)") 27 | case <-time.After(1 * time.Minute): 28 | fmt.Println("Timeout :-(") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/filtered_channels.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | client := pusher.NewClient("4115", "23ed642e81512118260e", "cd72de5494540704dcf1", false) 11 | 12 | done := make(chan bool) 13 | 14 | go func() { 15 | queryParameters := map[string]string{ 16 | "info": "user_count", 17 | "filter_by_prefix": "presence-", 18 | } 19 | channels, err := client.Channels(queryParameters) 20 | if err != nil { 21 | fmt.Printf("Error %s\n", err) 22 | } else { 23 | fmt.Println(channels) 24 | } 25 | done <- true 26 | }() 27 | 28 | select { 29 | case <-done: 30 | fmt.Println("Done :-)") 31 | case <-time.After(1 * time.Minute): 32 | fmt.Println("Timeout :-(") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/multi_publish.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "time" 7 | ) 8 | 9 | func main() { 10 | workers := 100 11 | messageCount := 5000 12 | messages := make(chan string) 13 | done := make(chan bool) 14 | 15 | client := pusher.NewClient("34420", "87bdfd3a6320e83b9289", "f25dfe88fb26ebf75139", false) 16 | 17 | for i := 0; i < workers; i++ { 18 | go func() { 19 | for data := range messages { 20 | err := client.Publish(data, "test", "test") 21 | if err != nil { 22 | fmt.Printf("E", err) 23 | } else { 24 | fmt.Print(".") 25 | } 26 | } 27 | }() 28 | } 29 | 30 | go func() { 31 | for i := 0; i < messageCount; i++ { 32 | messages <- "test" 33 | } 34 | done <- true 35 | close(messages) 36 | close(done) 37 | }() 38 | 39 | select { 40 | case <-done: 41 | fmt.Println("\nDone :-)") 42 | case <-time.After(1 * time.Minute): 43 | fmt.Println("\nTimeout :-(") 44 | } 45 | 46 | fmt.Println("") 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/examples/users.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/timonv/pusher" 6 | "sort" 7 | "time" 8 | ) 9 | 10 | func main() { 11 | client := pusher.NewClient("4115", "23ed642e81512118260e", "cd72de5494540704dcf1", false) 12 | 13 | done := make(chan bool) 14 | 15 | go func() { 16 | users, err := client.Users("common") 17 | if err != nil { 18 | fmt.Printf("Error %s\n", err) 19 | } else { 20 | ids := []int{} 21 | for k := range users.List { 22 | ids = append(ids, k) 23 | } 24 | sort.Ints(ids) 25 | fmt.Println("User Count:", len(ids)) 26 | fmt.Println(ids) 27 | } 28 | done <- true 29 | }() 30 | 31 | select { 32 | case <-done: 33 | fmt.Println("Done :-)") 34 | case <-time.After(1 * time.Minute): 35 | fmt.Println("Timeout :-(") 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/joshk/pusher/signature_test.go: -------------------------------------------------------------------------------- 1 | package pusher 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSign(t *testing.T) { 8 | signature := &Signature{ 9 | "key", 10 | "secret", 11 | "POST", 12 | "/some/path", 13 | "1234", 14 | "1.0", 15 | []byte("content"), 16 | map[string]string{"query": "params", "go": "here"}, 17 | } 18 | 19 | expected := "5da41b658c67bb135898072d6d325e7a98e5f790d9c7c70cc5e210173d81be52" 20 | sig := signature.Sign() 21 | if expected != sig { 22 | t.Errorf("Sign(): Expected %s, got %s", expected, sig) 23 | } 24 | } 25 | 26 | func TestEncodedQuery(t *testing.T) { 27 | signature := &Signature{ 28 | "key", 29 | "secret", 30 | "POST", 31 | "/some/path", 32 | "1234", 33 | "1.0", 34 | []byte("content"), 35 | map[string]string{"query": "params", "go": "here"}, 36 | } 37 | 38 | expected := "auth_key=key&auth_signature=5da41b658c67bb135898072d6d325e7a98e5f790d9c7c70cc5e210173d81be52&auth_timestamp=1234&auth_version=1.0&body_md5=9a0364b9e99bb480dd25e1f0284c8555&go=here&query=params" 39 | encodedQuery := signature.EncodedQuery() 40 | if expected != encodedQuery { 41 | t.Errorf("EncodedQuery(): Expected %s, got %s", expected, encodedQuery) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/githubauth/Readme.md: -------------------------------------------------------------------------------- 1 | ##### GitHub OAuth HTTP handler 2 | 3 | See for documentation. 4 | 5 | ###### Example 6 | 7 | ```go 8 | h := &githubauth.Handler{ 9 | RequireOrg: "mycorp", 10 | Keys: keys(), 11 | ClientID: os.Getenv("OAUTH_CLIENT_ID"), 12 | ClientSecret: os.Getenv("OAUTH_CLIENT_SECRET"), 13 | } 14 | http.ListenAndServe(":8080", h) 15 | ``` 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/kr/session/Readme: -------------------------------------------------------------------------------- 1 | basic http sessions with a nice interface 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/.gitignore: -------------------------------------------------------------------------------- 1 | .db 2 | *.test 3 | *~ 4 | *.swp 5 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to pq 2 | 3 | `pq` has a backlog of pull requests, but contributions are still very 4 | much welcome. You can help with patch review, submitting bug reports, 5 | or adding new functionality. There is no formal style guide, but 6 | please conform to the style of existing code and general Go formatting 7 | conventions when submitting patches. 8 | 9 | ### Patch review 10 | 11 | Help review existing open pull requests by commenting on the code or 12 | proposed functionality. 13 | 14 | ### Bug reports 15 | 16 | We appreciate any bug reports, but especially ones with self-contained 17 | (doesn't depend on code outside of pq), minimal (can't be simplified 18 | further) test cases. It's especially helpful if you can submit a pull 19 | request with just the failing test case (you'll probably want to 20 | pattern it after the tests in 21 | [conn_test.go](https://github.com/lib/pq/blob/master/conn_test.go). 22 | 23 | ### New functionality 24 | 25 | There are a number of pending patches for new functionality, so 26 | additional feature patches will take a while to merge. Still, patches 27 | are generally reviewed based on usefulness and complexity in addition 28 | to time-in-queue, so if you have a knockout idea, take a shot. Feel 29 | free to open an issue discussion your proposed patch beforehand. 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2013, 'pq' Contributors 2 | Portions Copyright (C) 2011 Blake Mizerany 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/buf.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "bytes" 5 | "encoding/binary" 6 | 7 | "github.com/lib/pq/oid" 8 | ) 9 | 10 | type readBuf []byte 11 | 12 | func (b *readBuf) int32() (n int) { 13 | n = int(int32(binary.BigEndian.Uint32(*b))) 14 | *b = (*b)[4:] 15 | return 16 | } 17 | 18 | func (b *readBuf) oid() (n oid.Oid) { 19 | n = oid.Oid(binary.BigEndian.Uint32(*b)) 20 | *b = (*b)[4:] 21 | return 22 | } 23 | 24 | func (b *readBuf) int16() (n int) { 25 | n = int(binary.BigEndian.Uint16(*b)) 26 | *b = (*b)[2:] 27 | return 28 | } 29 | 30 | func (b *readBuf) string() string { 31 | i := bytes.IndexByte(*b, 0) 32 | if i < 0 { 33 | errorf("invalid message format; expected string terminator") 34 | } 35 | s := (*b)[:i] 36 | *b = (*b)[i+1:] 37 | return string(s) 38 | } 39 | 40 | func (b *readBuf) next(n int) (v []byte) { 41 | v = (*b)[:n] 42 | *b = (*b)[n:] 43 | return 44 | } 45 | 46 | func (b *readBuf) byte() byte { 47 | return b.next(1)[0] 48 | } 49 | 50 | type writeBuf []byte 51 | 52 | func (b *writeBuf) int32(n int) { 53 | x := make([]byte, 4) 54 | binary.BigEndian.PutUint32(x, uint32(n)) 55 | *b = append(*b, x...) 56 | } 57 | 58 | func (b *writeBuf) int16(n int) { 59 | x := make([]byte, 2) 60 | binary.BigEndian.PutUint16(x, uint16(n)) 61 | *b = append(*b, x...) 62 | } 63 | 64 | func (b *writeBuf) string(s string) { 65 | *b = append(*b, (s + "\000")...) 66 | } 67 | 68 | func (b *writeBuf) byte(c byte) { 69 | *b = append(*b, c) 70 | } 71 | 72 | func (b *writeBuf) bytes(v []byte) { 73 | *b = append(*b, v...) 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/certs/README: -------------------------------------------------------------------------------- 1 | This directory contains certificates and private keys for testing some 2 | SSL-related functionality in Travis. Do NOT use these certificates for 3 | anything other than testing. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/certs/postgresql.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICWwIBAAKBgQDjjAaacFRR0TQ0gznNolkPBe2N2A400JL0CU3ujHhVSST4POA0 3 | WAKy55RYwejlu9Gv9lTBQLGQcHkNNVScjxbpwvCS5mRJOMF2+EdmxFtKtqlDzsi+ 4 | bE0rlJc8VbzR0G63U66JXEtrhkC+wa4eZM6crocKaeXIIRK+rh32Rd8WpwIDAQAB 5 | AoGAM5dM6/kp9P700i8qjOgRPym96Zoh5nGfz/rIE5z/r36NBkdvIg8OVZfR96nH 6 | b0b9TOMR5lsPp0sI9yivTWvX6qyvLJRWy2vvx17hXK9NxXUNTAm0PYZUTvCtcPeX 7 | RnJpzQKNZQPkFzF0uXBc4CtPK2Vz0+FGvAelrhYAxnw1dIkCQQD+9qaW5QhXjsjb 8 | Nl85CmXgxPmGROcgLQCO+omfrjf9UXrituU9Dz6auym5lDGEdMFnkzfr+wpasEy9 9 | mf5ZZOhDAkEA5HjXfVGaCtpydOt6hDon/uZsyssCK2lQ7NSuE3vP+sUsYMzIpEoy 10 | t3VWXqKbo+g9KNDTP4WEliqp1aiSIylzzQJANPeqzihQnlgEdD4MdD4rwhFJwVIp 11 | Le8Lcais1KaN7StzOwxB/XhgSibd2TbnPpw+3bSg5n5lvUdo+e62/31OHwJAU1jS 12 | I+F09KikQIr28u3UUWT2IzTT4cpVv1AHAQyV3sG3YsjSGT0IK20eyP9BEBZU2WL0 13 | 7aNjrvR5aHxKc5FXsQJABsFtyGpgI5X4xufkJZVZ+Mklz2n7iXa+XPatMAHFxAtb 14 | EEMt60rngwMjXAzBSC6OYuYogRRAY3UCacNC5VhLYQ== 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/certs/root.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEAzCCAuugAwIBAgIJANmheROCdW1NMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNV 3 | BAYTAlVTMQ8wDQYDVQQIEwZOZXZhZGExEjAQBgNVBAcTCUxhcyBWZWdhczEaMBgG 4 | A1UEChMRZ2l0aHViLmNvbS9saWIvcHExDjAMBgNVBAMTBXBxIENBMB4XDTE0MTAx 5 | MTE1MDQyOVoXDTI0MTAwODE1MDQyOVowXjELMAkGA1UEBhMCVVMxDzANBgNVBAgT 6 | Bk5ldmFkYTESMBAGA1UEBxMJTGFzIFZlZ2FzMRowGAYDVQQKExFnaXRodWIuY29t 7 | L2xpYi9wcTEOMAwGA1UEAxMFcHEgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw 8 | ggEKAoIBAQCV4PxP7ShzWBzUCThcKk3qZtOLtHmszQVtbqhvgTpm1kTRtKBdVMu0 9 | pLAHQ3JgJCnAYgH0iZxVGoMP16T3irdgsdC48+nNTFM2T0cCdkfDURGIhSFN47cb 10 | Pgy306BcDUD2q7ucW33+dlFSRuGVewocoh4BWM/vMtMvvWzdi4Ag/L/jhb+5wZxZ 11 | sWymsadOVSDePEMKOvlCa3EdVwVFV40TVyDb+iWBUivDAYsS2a3KajuJrO6MbZiE 12 | Sp2RCIkZS2zFmzWxVRi9ZhzIZhh7EVF9JAaNC3T52jhGUdlRq3YpBTMnd89iOh74 13 | 6jWXG7wSuPj3haFzyNhmJ0ZUh+2Ynoh1AgMBAAGjgcMwgcAwHQYDVR0OBBYEFFKT 14 | 7R52Cp9lT94ZZsHVIkA1y6ByMIGQBgNVHSMEgYgwgYWAFFKT7R52Cp9lT94ZZsHV 15 | IkA1y6ByoWKkYDBeMQswCQYDVQQGEwJVUzEPMA0GA1UECBMGTmV2YWRhMRIwEAYD 16 | VQQHEwlMYXMgVmVnYXMxGjAYBgNVBAoTEWdpdGh1Yi5jb20vbGliL3BxMQ4wDAYD 17 | VQQDEwVwcSBDQYIJANmheROCdW1NMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF 18 | BQADggEBAAEhCLWkqJNMI8b4gkbmj5fqQ/4+oO83bZ3w2Oqf6eZ8I8BC4f2NOyE6 19 | tRUlq5+aU7eqC1cOAvGjO+YHN/bF/DFpwLlzvUSXt+JP/pYcUjL7v+pIvwqec9hD 20 | ndvM4iIbkD/H/OYQ3L+N3W+G1x7AcFIX+bGCb3PzYVQAjxreV6//wgKBosMGFbZo 21 | HPxT9RPMun61SViF04H5TNs0derVn1+5eiiYENeAhJzQNyZoOOUuX1X/Inx9bEPh 22 | C5vFBtSMgIytPgieRJVWAiMLYsfpIAStrHztRAbBs2DU01LmMgRvHdxgFEKinC/d 23 | UHZZQDP+6pT+zADrGhQGXe4eThaO6f0= 24 | -----END CERTIFICATE----- 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEA14pMhfsXpTyP4HIRKc4/sB8/fcbuf6f8Ais1RwimPZDfXFYU 3 | lADHbdHS4mGVd7jjpmYx+R8hfWLhJ9qUN2FK6mNToGG4nLul4ue3ptgPBQTHKeLq 4 | SSt/3hUAphhwUMcM3pr5Wpaw4ZQGxm1KITu0D6VtkoY0sk7XDqcZwHcLe4fIkt5C 5 | /4bSt5qk1BUjyq2laSG4zn5my4Vdue2LLQmNlOQEHnLs79B2kBVapPeRS+nOTp1d 6 | mnAXnNjpc4PqPWGZps2skUBaiHflTiqOPRPz+ThvgWuKlcoOB6tv2rSM2f+qeAOq 7 | x8LPb2SS09iD1a/xIxinLnsXC+d98fqoQaMEVwIDAQABAoIBAF3ZoihUhJ82F4+r 8 | Gz4QyDpv4L1reT2sb1aiabhcU8ZK5nbWJG+tRyjSS/i2dNaEcttpdCj9HR/zhgZM 9 | bm0OuAgG58rVwgS80CZUruq++Qs+YVojq8/gWPTiQD4SNhV2Fmx3HkwLgUk3oxuT 10 | SsvdqzGE3okGVrutCIcgy126eA147VPMoej1Bb3fO6npqK0pFPhZfAc0YoqJuM+k 11 | obRm5pAnGUipyLCFXjA9HYPKwYZw2RtfdA3CiImHeanSdqS+ctrC9y8BV40Th7gZ 12 | haXdKUNdjmIxV695QQ1mkGqpKLZFqhzKioGQ2/Ly2d1iaKN9fZltTusu8unepWJ2 13 | tlT9qMECgYEA9uHaF1t2CqE+AJvWTihHhPIIuLxoOQXYea1qvxfcH/UMtaLKzCNm 14 | lQ5pqCGsPvp+10f36yttO1ZehIvlVNXuJsjt0zJmPtIolNuJY76yeussfQ9jHheB 15 | 5uPEzCFlHzxYbBUyqgWaF6W74okRGzEGJXjYSP0yHPPdU4ep2q3bGiUCgYEA34Af 16 | wBSuQSK7uLxArWHvQhyuvi43ZGXls6oRGl+Ysj54s8BP6XGkq9hEJ6G4yxgyV+BR 17 | DUOs5X8/TLT8POuIMYvKTQthQyCk0eLv2FLdESDuuKx0kBVY3s8lK3/z5HhrdOiN 18 | VMNZU+xDKgKc3hN9ypkk8vcZe6EtH7Y14e0rVcsCgYBTgxi8F/M5K0wG9rAqphNz 19 | VFBA9XKn/2M33cKjO5X5tXIEKzpAjaUQvNxexG04rJGljzG8+mar0M6ONahw5yD1 20 | O7i/XWgazgpuOEkkVYiYbd8RutfDgR4vFVMn3hAP3eDnRtBplRWH9Ec3HTiNIys6 21 | F8PKBOQjyRZQQC7jyzW3hQKBgACe5HeuFwXLSOYsb6mLmhR+6+VPT4wR1F95W27N 22 | USk9jyxAnngxfpmTkiziABdgS9N+pfr5cyN4BP77ia/Jn6kzkC5Cl9SN5KdIkA3z 23 | vPVtN/x/ThuQU5zaymmig1ThGLtMYggYOslG4LDfLPxY5YKIhle+Y+259twdr2yf 24 | Mf2dAoGAaGv3tWMgnIdGRk6EQL/yb9PKHo7ShN+tKNlGaK7WwzBdKs+Fe8jkgcr7 25 | pz4Ne887CmxejdISzOCcdT+Zm9Bx6I/uZwWOtDvWpIgIxVX9a9URj/+D1MxTE/y4 26 | d6H+c89yDY62I2+drMpdjCd3EtCaTlxpTbRS+s1eAHMH7aEkcCE= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/oid/doc.go: -------------------------------------------------------------------------------- 1 | // Package oid contains OID constants 2 | // as defined by the Postgres server. 3 | package oid 4 | 5 | // Oid is a Postgres Object ID. 6 | type Oid uint32 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/oid/gen.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // Generate the table of OID values 4 | // Run with 'go run gen.go'. 5 | package main 6 | 7 | import ( 8 | "database/sql" 9 | "fmt" 10 | "log" 11 | "os" 12 | "os/exec" 13 | 14 | _ "github.com/lib/pq" 15 | ) 16 | 17 | func main() { 18 | datname := os.Getenv("PGDATABASE") 19 | sslmode := os.Getenv("PGSSLMODE") 20 | 21 | if datname == "" { 22 | os.Setenv("PGDATABASE", "pqgotest") 23 | } 24 | 25 | if sslmode == "" { 26 | os.Setenv("PGSSLMODE", "disable") 27 | } 28 | 29 | db, err := sql.Open("postgres", "") 30 | if err != nil { 31 | log.Fatal(err) 32 | } 33 | cmd := exec.Command("gofmt") 34 | cmd.Stderr = os.Stderr 35 | w, err := cmd.StdinPipe() 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | f, err := os.Create("types.go") 40 | if err != nil { 41 | log.Fatal(err) 42 | } 43 | cmd.Stdout = f 44 | err = cmd.Start() 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | fmt.Fprintln(w, "// generated by 'go run gen.go'; do not edit") 49 | fmt.Fprintln(w, "\npackage oid") 50 | fmt.Fprintln(w, "const (") 51 | rows, err := db.Query(` 52 | SELECT typname, oid 53 | FROM pg_type WHERE oid < 10000 54 | ORDER BY oid; 55 | `) 56 | if err != nil { 57 | log.Fatal(err) 58 | } 59 | var name string 60 | var oid int 61 | for rows.Next() { 62 | err = rows.Scan(&name, &oid) 63 | if err != nil { 64 | log.Fatal(err) 65 | } 66 | fmt.Fprintf(w, "T_%s Oid = %d\n", name, oid) 67 | } 68 | if err = rows.Err(); err != nil { 69 | log.Fatal(err) 70 | } 71 | fmt.Fprintln(w, ")") 72 | w.Close() 73 | cmd.Wait() 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/url.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "fmt" 5 | nurl "net/url" 6 | "sort" 7 | "strings" 8 | ) 9 | 10 | // ParseURL no longer needs to be used by clients of this library since supplying a URL as a 11 | // connection string to sql.Open() is now supported: 12 | // 13 | // sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full") 14 | // 15 | // It remains exported here for backwards-compatibility. 16 | // 17 | // ParseURL converts a url to a connection string for driver.Open. 18 | // Example: 19 | // 20 | // "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full" 21 | // 22 | // converts to: 23 | // 24 | // "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full" 25 | // 26 | // A minimal example: 27 | // 28 | // "postgres://" 29 | // 30 | // This will be blank, causing driver.Open to use all of the defaults 31 | func ParseURL(url string) (string, error) { 32 | u, err := nurl.Parse(url) 33 | if err != nil { 34 | return "", err 35 | } 36 | 37 | if u.Scheme != "postgres" { 38 | return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) 39 | } 40 | 41 | var kvs []string 42 | escaper := strings.NewReplacer(` `, `\ `, `'`, `\'`, `\`, `\\`) 43 | accrue := func(k, v string) { 44 | if v != "" { 45 | kvs = append(kvs, k+"="+escaper.Replace(v)) 46 | } 47 | } 48 | 49 | if u.User != nil { 50 | v := u.User.Username() 51 | accrue("user", v) 52 | 53 | v, _ = u.User.Password() 54 | accrue("password", v) 55 | } 56 | 57 | i := strings.Index(u.Host, ":") 58 | if i < 0 { 59 | accrue("host", u.Host) 60 | } else { 61 | accrue("host", u.Host[:i]) 62 | accrue("port", u.Host[i+1:]) 63 | } 64 | 65 | if u.Path != "" { 66 | accrue("dbname", u.Path[1:]) 67 | } 68 | 69 | q := u.Query() 70 | for k := range q { 71 | accrue(k, q.Get(k)) 72 | } 73 | 74 | sort.Strings(kvs) // Makes testing easier (not a performance concern) 75 | return strings.Join(kvs, " "), nil 76 | } 77 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/url_test.go: -------------------------------------------------------------------------------- 1 | package pq 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSimpleParseURL(t *testing.T) { 8 | expected := "host=hostname.remote" 9 | str, err := ParseURL("postgres://hostname.remote") 10 | if err != nil { 11 | t.Fatal(err) 12 | } 13 | 14 | if str != expected { 15 | t.Fatalf("unexpected result from ParseURL:\n+ %v\n- %v", str, expected) 16 | } 17 | } 18 | 19 | func TestFullParseURL(t *testing.T) { 20 | expected := `dbname=database host=hostname.remote password=top\ secret port=1234 user=username` 21 | str, err := ParseURL("postgres://username:top%20secret@hostname.remote:1234/database") 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | if str != expected { 27 | t.Fatalf("unexpected result from ParseURL:\n+ %s\n- %s", str, expected) 28 | } 29 | } 30 | 31 | func TestInvalidProtocolParseURL(t *testing.T) { 32 | _, err := ParseURL("http://hostname.remote") 33 | switch err { 34 | case nil: 35 | t.Fatal("Expected an error from parsing invalid protocol") 36 | default: 37 | msg := "invalid connection protocol: http" 38 | if err.Error() != msg { 39 | t.Fatalf("Unexpected error message:\n+ %s\n- %s", 40 | err.Error(), msg) 41 | } 42 | } 43 | } 44 | 45 | func TestMinimalURL(t *testing.T) { 46 | cs, err := ParseURL("postgres://") 47 | if err != nil { 48 | t.Fatal(err) 49 | } 50 | 51 | if cs != "" { 52 | t.Fatalf("expected blank connection string, got: %q", cs) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/user_posix.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | 3 | // +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris 4 | 5 | package pq 6 | 7 | import ( 8 | "os" 9 | "os/user" 10 | ) 11 | 12 | func userCurrent() (string, error) { 13 | u, err := user.Current() 14 | if err == nil { 15 | return u.Username, nil 16 | } 17 | 18 | name := os.Getenv("USER") 19 | if name != "" { 20 | return name, nil 21 | } 22 | 23 | return "", ErrCouldNotDetectUsername 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/lib/pq/user_windows.go: -------------------------------------------------------------------------------- 1 | // Package pq is a pure Go Postgres driver for the database/sql package. 2 | package pq 3 | 4 | import ( 5 | "path/filepath" 6 | "syscall" 7 | ) 8 | 9 | // Perform Windows user name lookup identically to libpq. 10 | // 11 | // The PostgreSQL code makes use of the legacy Win32 function 12 | // GetUserName, and that function has not been imported into stock Go. 13 | // GetUserNameEx is available though, the difference being that a 14 | // wider range of names are available. To get the output to be the 15 | // same as GetUserName, only the base (or last) component of the 16 | // result is returned. 17 | func userCurrent() (string, error) { 18 | pw_name := make([]uint16, 128) 19 | pwname_size := uint32(len(pw_name)) - 1 20 | err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size) 21 | if err != nil { 22 | return "", ErrCouldNotDetectUsername 23 | } 24 | s := syscall.UTF16ToString(pw_name) 25 | u := filepath.Base(s) 26 | return u, nil 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/bash/README.md: -------------------------------------------------------------------------------- 1 | # Bash Driver 2 | 3 | * Runs bash scripts. What you do in the scripts is up to you. 4 | 5 | ## Usage 6 | 7 | ```bash 8 | migrate -url bash://xxx -path ./migrations create increment_xyz 9 | migrate -url bash://xxx -path ./migrations up 10 | migrate help # for more info 11 | ``` -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/bash/bash.go: -------------------------------------------------------------------------------- 1 | // Package bash implements the Driver interface. 2 | package bash 3 | 4 | import ( 5 | "github.com/mattes/migrate/file" 6 | _ "github.com/mattes/migrate/migrate/direction" 7 | ) 8 | 9 | type Driver struct { 10 | } 11 | 12 | func (driver *Driver) Initialize(url string) error { 13 | return nil 14 | } 15 | 16 | func (driver *Driver) Close() error { 17 | return nil 18 | } 19 | 20 | func (driver *Driver) FilenameExtension() string { 21 | return "sh" 22 | } 23 | 24 | func (driver *Driver) Migrate(f file.File, pipe chan interface{}) { 25 | defer close(pipe) 26 | pipe <- f 27 | return 28 | } 29 | 30 | func (driver *Driver) Version() (uint64, error) { 31 | return uint64(0), nil 32 | } 33 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/bash/bash_test.go: -------------------------------------------------------------------------------- 1 | package bash 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestMigrate(t *testing.T) { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/cassandra/README.md: -------------------------------------------------------------------------------- 1 | # Cassandra Driver 2 | 3 | ## Usage 4 | 5 | ```bash 6 | migrate -url cassandra://host:port/keyspace -path ./db/migrations create add_field_to_table 7 | migrate -url cassandra://host:port/keyspace -path ./db/migrations up 8 | migrate help # for more info 9 | ``` 10 | 11 | ## Authors 12 | 13 | * Paul Bergeron, https://github.com/dinedal -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/driver_test.go: -------------------------------------------------------------------------------- 1 | package driver 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNew(t *testing.T) { 8 | if _, err := New("unknown://url"); err == nil { 9 | t.Error("no error although driver unknown") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/mysql/README.md: -------------------------------------------------------------------------------- 1 | # MySQL Driver 2 | 3 | ### See [issue #1](https://github.com/mattes/migrate/issues/1#issuecomment-58728186) before using this driver! 4 | 5 | * Runs migrations in transcations. 6 | That means that if a migration failes, it will be safely rolled back. 7 | * Tries to return helpful error messages. 8 | * Stores migration version details in table ``schema_migrations``. 9 | This table will be auto-generated. 10 | 11 | 12 | ## Usage 13 | 14 | ```bash 15 | migrate -url mysql://user@tcp(host:port)/database -path ./db/migrations create add_field_to_table 16 | migrate -url mysql://user@tcp(host:port)/database -path ./db/migrations up 17 | migrate help # for more info 18 | ``` 19 | 20 | See full [DSN (Data Source Name) documentation](https://github.com/go-sql-driver/mysql/#dsn-data-source-name). 21 | 22 | ## Authors 23 | 24 | * Matthias Kadenbach, https://github.com/mattes -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/driver/postgres/README.md: -------------------------------------------------------------------------------- 1 | # PostgreSQL Driver 2 | 3 | * Runs migrations in transcations. 4 | That means that if a migration failes, it will be safely rolled back. 5 | * Tries to return helpful error messages. 6 | * Stores migration version details in table ``schema_migrations``. 7 | This table will be auto-generated. 8 | 9 | 10 | ## Usage 11 | 12 | ```bash 13 | migrate -url postgres://user@host:port/database -path ./db/migrations create add_field_to_table 14 | migrate -url postgres://user@host:port/database -path ./db/migrations up 15 | migrate help # for more info 16 | 17 | # TODO(mattes): thinking about adding some custom flag to allow migration within schemas: 18 | -url="postgres://user@host:port/database?schema=name" 19 | ``` 20 | 21 | ## Authors 22 | 23 | * Matthias Kadenbach, https://github.com/mattes -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/migrate/direction/direction.go: -------------------------------------------------------------------------------- 1 | // Package direction just holds convenience constants for Up and Down migrations. 2 | package direction 3 | 4 | type Direction int 5 | 6 | const ( 7 | Up Direction = +1 8 | Down = -1 9 | ) 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/mattes/migrate/pipe/pipe.go: -------------------------------------------------------------------------------- 1 | // Package pipe has functions for pipe channel handling. 2 | package pipe 3 | 4 | import ( 5 | "os" 6 | ) 7 | 8 | // New creates a new pipe. A pipe is basically a channel. 9 | func New() chan interface{} { 10 | return make(chan interface{}, 0) 11 | } 12 | 13 | // Close closes a pipe and optionally sends an error 14 | func Close(pipe chan interface{}, err error) { 15 | if err != nil { 16 | pipe <- err 17 | } 18 | close(pipe) 19 | } 20 | 21 | // WaitAndRedirect waits for pipe to be closed and 22 | // redirects all messages from pipe to redirectPipe 23 | // while it waits. It also checks if there was an 24 | // interrupt send and will quit gracefully if yes. 25 | func WaitAndRedirect(pipe, redirectPipe chan interface{}, interrupt chan os.Signal) (ok bool) { 26 | errorReceived := false 27 | interruptsReceived := 0 28 | if pipe != nil && redirectPipe != nil { 29 | for { 30 | select { 31 | 32 | case <-interrupt: 33 | interruptsReceived += 1 34 | if interruptsReceived > 1 { 35 | os.Exit(5) 36 | } else { 37 | // add white space at beginning for ^C splitting 38 | redirectPipe <- " Aborting after this migration ... Hit again to force quit." 39 | } 40 | 41 | case item, ok := <-pipe: 42 | if !ok { 43 | return !errorReceived && interruptsReceived == 0 44 | } else { 45 | redirectPipe <- item 46 | switch item.(type) { 47 | case error: 48 | errorReceived = true 49 | } 50 | } 51 | } 52 | } 53 | } 54 | return !errorReceived && interruptsReceived == 0 55 | } 56 | 57 | // ReadErrors selects all received errors and returns them. 58 | // This is helpful for synchronous migration functions. 59 | func ReadErrors(pipe chan interface{}) []error { 60 | err := make([]error, 0) 61 | if pipe != nil { 62 | for { 63 | select { 64 | case item, ok := <-pipe: 65 | if !ok { 66 | return err 67 | } else { 68 | switch item.(type) { 69 | case error: 70 | err = append(err, item.(error)) 71 | } 72 | } 73 | } 74 | } 75 | } 76 | return err 77 | } 78 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/poly1305/const_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo 9 | 10 | DATA ·SCALE(SB)/8, $0x37F4000000000000 11 | GLOBL ·SCALE(SB), 8, $8 12 | DATA ·TWO32(SB)/8, $0x41F0000000000000 13 | GLOBL ·TWO32(SB), 8, $8 14 | DATA ·TWO64(SB)/8, $0x43F0000000000000 15 | GLOBL ·TWO64(SB), 8, $8 16 | DATA ·TWO96(SB)/8, $0x45F0000000000000 17 | GLOBL ·TWO96(SB), 8, $8 18 | DATA ·ALPHA32(SB)/8, $0x45E8000000000000 19 | GLOBL ·ALPHA32(SB), 8, $8 20 | DATA ·ALPHA64(SB)/8, $0x47E8000000000000 21 | GLOBL ·ALPHA64(SB), 8, $8 22 | DATA ·ALPHA96(SB)/8, $0x49E8000000000000 23 | GLOBL ·ALPHA96(SB), 8, $8 24 | DATA ·ALPHA130(SB)/8, $0x4C08000000000000 25 | GLOBL ·ALPHA130(SB), 8, $8 26 | DATA ·DOFFSET0(SB)/8, $0x4330000000000000 27 | GLOBL ·DOFFSET0(SB), 8, $8 28 | DATA ·DOFFSET1(SB)/8, $0x4530000000000000 29 | GLOBL ·DOFFSET1(SB), 8, $8 30 | DATA ·DOFFSET2(SB)/8, $0x4730000000000000 31 | GLOBL ·DOFFSET2(SB), 8, $8 32 | DATA ·DOFFSET3(SB)/8, $0x4930000000000000 33 | GLOBL ·DOFFSET3(SB), 8, $8 34 | DATA ·DOFFSET3MINUSTWO128(SB)/8, $0x492FFFFE00000000 35 | GLOBL ·DOFFSET3MINUSTWO128(SB), 8, $8 36 | DATA ·HOFFSET0(SB)/8, $0x43300001FFFFFFFB 37 | GLOBL ·HOFFSET0(SB), 8, $8 38 | DATA ·HOFFSET1(SB)/8, $0x45300001FFFFFFFE 39 | GLOBL ·HOFFSET1(SB), 8, $8 40 | DATA ·HOFFSET2(SB)/8, $0x47300001FFFFFFFE 41 | GLOBL ·HOFFSET2(SB), 8, $8 42 | DATA ·HOFFSET3(SB)/8, $0x49300003FFFFFFFE 43 | GLOBL ·HOFFSET3(SB), 8, $8 44 | DATA ·ROUNDING(SB)/2, $0x137f 45 | GLOBL ·ROUNDING(SB), 8, $2 46 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package poly1305 implements Poly1305 one-time message authentication code as specified in http://cr.yp.to/mac/poly1305-20050329.pdf. 7 | 8 | Poly1305 is a fast, one-time authentication function. It is infeasible for an 9 | attacker to generate an authenticator for a message without the key. However, a 10 | key must only be used for a single message. Authenticating two different 11 | messages with the same key allows an attacker to forge authenticators for other 12 | messages with the same key. 13 | 14 | Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was 15 | used with a fixed key in order to generate one-time keys from an nonce. 16 | However, in this package AES isn't used and the one-time key is specified 17 | directly. 18 | */ 19 | package poly1305 20 | 21 | import "crypto/subtle" 22 | 23 | // TagSize is the size, in bytes, of a poly1305 authenticator. 24 | const TagSize = 16 25 | 26 | // Verify returns true if mac is a valid authenticator for m with the given 27 | // key. 28 | func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { 29 | var tmp [16]byte 30 | Sum(&tmp, m, key) 31 | return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 32 | } 33 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/poly1305/poly1305_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package poly1305 6 | 7 | import ( 8 | "bytes" 9 | "testing" 10 | ) 11 | 12 | var testData = []struct { 13 | in, k, correct []byte 14 | }{ 15 | { 16 | []byte("Hello world!"), 17 | []byte("this is 32-byte key for Poly1305"), 18 | []byte{0xa6, 0xf7, 0x45, 0x00, 0x8f, 0x81, 0xc9, 0x16, 0xa2, 0x0d, 0xcc, 0x74, 0xee, 0xf2, 0xb2, 0xf0}, 19 | }, 20 | { 21 | make([]byte, 32), 22 | []byte("this is 32-byte key for Poly1305"), 23 | []byte{0x49, 0xec, 0x78, 0x09, 0x0e, 0x48, 0x1e, 0xc6, 0xc2, 0x6b, 0x33, 0xb9, 0x1c, 0xcc, 0x03, 0x07}, 24 | }, 25 | { 26 | make([]byte, 2007), 27 | []byte("this is 32-byte key for Poly1305"), 28 | []byte{0xda, 0x84, 0xbc, 0xab, 0x02, 0x67, 0x6c, 0x38, 0xcd, 0xb0, 0x15, 0x60, 0x42, 0x74, 0xc2, 0xaa}, 29 | }, 30 | { 31 | make([]byte, 2007), 32 | make([]byte, 32), 33 | make([]byte, 16), 34 | }, 35 | } 36 | 37 | func TestSum(t *testing.T) { 38 | var out [16]byte 39 | var key [32]byte 40 | 41 | for i, v := range testData { 42 | copy(key[:], v.k) 43 | Sum(&out, v.in, &key) 44 | if !bytes.Equal(out[:], v.correct) { 45 | t.Errorf("%d: expected %x, got %x", i, v.correct, out[:]) 46 | } 47 | } 48 | } 49 | 50 | func Benchmark1K(b *testing.B) { 51 | b.StopTimer() 52 | var out [16]byte 53 | var key [32]byte 54 | in := make([]byte, 1024) 55 | b.SetBytes(int64(len(in))) 56 | b.StartTimer() 57 | 58 | for i := 0; i < b.N; i++ { 59 | Sum(&out, in, &key) 60 | } 61 | } 62 | 63 | func Benchmark64(b *testing.B) { 64 | b.StopTimer() 65 | var out [16]byte 66 | var key [32]byte 67 | in := make([]byte, 64) 68 | b.SetBytes(int64(len(in))) 69 | b.StartTimer() 70 | 71 | for i := 0; i < b.N; i++ { 72 | Sum(&out, in, &key) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/poly1305/sum_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!gccgo 6 | 7 | package poly1305 8 | 9 | // This function is implemented in poly1305_amd64.s 10 | 11 | //go:noescape 12 | 13 | func poly1305(out *[16]byte, m *byte, mlen uint64, key *[32]byte) 14 | 15 | // Sum generates an authenticator for m using a one-time key and puts the 16 | // 16-byte result into out. Authenticating two different messages with the same 17 | // key allows an attacker to forge messages at will. 18 | func Sum(out *[16]byte, m []byte, key *[32]byte) { 19 | var mPtr *byte 20 | if len(m) > 0 { 21 | mPtr = &m[0] 22 | } 23 | poly1305(out, mPtr, uint64(len(m)), key) 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build amd64,!appengine,!gccgo 6 | 7 | package salsa 8 | 9 | // This function is implemented in salsa2020_amd64.s. 10 | 11 | //go:noescape 12 | 13 | func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) 14 | 15 | // XORKeyStream crypts bytes from in to out using the given key and counters. 16 | // In and out may be the same slice but otherwise should not overlap. Counter 17 | // contains the raw salsa20 counter bytes (both nonce and block counter). 18 | func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { 19 | if len(in) == 0 { 20 | return 21 | } 22 | salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0]) 23 | } 24 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/crypto/salsa20/salsa/salsa_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package salsa 6 | 7 | import "testing" 8 | 9 | func TestCore208(t *testing.T) { 10 | in := [64]byte{ 11 | 0x7e, 0x87, 0x9a, 0x21, 0x4f, 0x3e, 0xc9, 0x86, 12 | 0x7c, 0xa9, 0x40, 0xe6, 0x41, 0x71, 0x8f, 0x26, 13 | 0xba, 0xee, 0x55, 0x5b, 0x8c, 0x61, 0xc1, 0xb5, 14 | 0x0d, 0xf8, 0x46, 0x11, 0x6d, 0xcd, 0x3b, 0x1d, 15 | 0xee, 0x24, 0xf3, 0x19, 0xdf, 0x9b, 0x3d, 0x85, 16 | 0x14, 0x12, 0x1e, 0x4b, 0x5a, 0xc5, 0xaa, 0x32, 17 | 0x76, 0x02, 0x1d, 0x29, 0x09, 0xc7, 0x48, 0x29, 18 | 0xed, 0xeb, 0xc6, 0x8d, 0xb8, 0xb8, 0xc2, 0x5e} 19 | 20 | out := [64]byte{ 21 | 0xa4, 0x1f, 0x85, 0x9c, 0x66, 0x08, 0xcc, 0x99, 22 | 0x3b, 0x81, 0xca, 0xcb, 0x02, 0x0c, 0xef, 0x05, 23 | 0x04, 0x4b, 0x21, 0x81, 0xa2, 0xfd, 0x33, 0x7d, 24 | 0xfd, 0x7b, 0x1c, 0x63, 0x96, 0x68, 0x2f, 0x29, 25 | 0xb4, 0x39, 0x31, 0x68, 0xe3, 0xc9, 0xe6, 0xbc, 26 | 0xfe, 0x6b, 0xc5, 0xb7, 0xa0, 0x6d, 0x96, 0xba, 27 | 0xe4, 0x24, 0xcc, 0x10, 0x2c, 0x91, 0x74, 0x5c, 28 | 0x24, 0xad, 0x67, 0x3d, 0xc7, 0x61, 0x8f, 0x81, 29 | } 30 | 31 | Core208(&in, &in) 32 | if in != out { 33 | t.Errorf("expected %x, got %x", out, in) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/net/context/withtimeout_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package context_test 6 | 7 | import ( 8 | "fmt" 9 | "time" 10 | 11 | "golang.org/x/net/context" 12 | ) 13 | 14 | func ExampleWithTimeout() { 15 | // Pass a context with a timeout to tell a blocking function that it 16 | // should abandon its work after the timeout elapses. 17 | ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) 18 | select { 19 | case <-time.After(200 * time.Millisecond): 20 | fmt.Println("overslept") 21 | case <-ctx.Done(): 22 | fmt.Println(ctx.Err()) // prints "context deadline exceeded" 23 | } 24 | // Output: 25 | // context deadline exceeded 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.3 5 | - 1.4 6 | 7 | install: 8 | - export GOPATH="$HOME/gopath" 9 | - mkdir -p "$GOPATH/src/golang.org/x" 10 | - mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/golang.org/x/oauth2" 11 | - go get -v -t -d golang.org/x/oauth2/... 12 | 13 | script: 14 | - go test -v golang.org/x/oauth2/... 15 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Go 2 | 3 | Go is an open source project. 4 | 5 | It is the work of hundreds of contributors. We appreciate your help! 6 | 7 | 8 | ## Filing issues 9 | 10 | When [filing an issue](https://github.com/golang/oauth2/issues), make sure to answer these five questions: 11 | 12 | 1. What version of Go are you using (`go version`)? 13 | 2. What operating system and processor architecture are you using? 14 | 3. What did you do? 15 | 4. What did you expect to see? 16 | 5. What did you see instead? 17 | 18 | General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. 19 | The gophers there will answer or ask you to file an issue if you've tripped over a bug. 20 | 21 | ## Contributing code 22 | 23 | Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) 24 | before sending patches. 25 | 26 | **We do not accept GitHub pull requests** 27 | (we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). 28 | 29 | Unless otherwise noted, the Go source files are distributed under 30 | the BSD-style license found in the LICENSE file. 31 | 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The oauth2 Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/client_appengine.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine appenginevm 6 | 7 | // App Engine hooks. 8 | 9 | package oauth2 10 | 11 | import ( 12 | "net/http" 13 | 14 | "golang.org/x/net/context" 15 | "google.golang.org/appengine/urlfetch" 16 | ) 17 | 18 | func init() { 19 | registerContextClientFunc(contextClientAppEngine) 20 | } 21 | 22 | func contextClientAppEngine(ctx context.Context) (*http.Client, error) { 23 | return urlfetch.Client(ctx), nil 24 | } 25 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2_test 6 | 7 | import ( 8 | "fmt" 9 | "log" 10 | 11 | "golang.org/x/oauth2" 12 | ) 13 | 14 | func ExampleConfig() { 15 | conf := &oauth2.Config{ 16 | ClientID: "YOUR_CLIENT_ID", 17 | ClientSecret: "YOUR_CLIENT_SECRET", 18 | Scopes: []string{"SCOPE1", "SCOPE2"}, 19 | Endpoint: oauth2.Endpoint{ 20 | AuthURL: "https://provider.com/o/oauth2/auth", 21 | TokenURL: "https://provider.com/o/oauth2/token", 22 | }, 23 | } 24 | 25 | // Redirect user to consent page to ask for permission 26 | // for the scopes specified above. 27 | url := conf.AuthCodeURL("state", oauth2.AccessTypeOffline) 28 | fmt.Printf("Visit the URL for the auth dialog: %v", url) 29 | 30 | // Use the authorization code that is pushed to the redirect URL. 31 | // NewTransportWithCode will do the handshake to retrieve 32 | // an access token and initiate a Transport that is 33 | // authorized and authenticated by the retrieved token. 34 | var code string 35 | if _, err := fmt.Scan(&code); err != nil { 36 | log.Fatal(err) 37 | } 38 | tok, err := conf.Exchange(oauth2.NoContext, code) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | 43 | client := conf.Client(oauth2.NoContext, tok) 44 | client.Get("...") 45 | } 46 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/facebook/facebook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package facebook provides constants for using OAuth2 to access Facebook. 6 | package facebook 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Facebook's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.facebook.com/dialog/oauth", 15 | TokenURL: "https://graph.facebook.com/oauth/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/github/github.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package github provides constants for using OAuth2 to access Github. 6 | package github 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Github's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://github.com/login/oauth/authorize", 15 | TokenURL: "https://github.com/login/oauth/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/appengine_hook.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build appengine appenginevm 6 | 7 | package google 8 | 9 | import "google.golang.org/appengine" 10 | 11 | func init() { 12 | appengineTokenFunc = appengine.AccessToken 13 | } 14 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/sdk_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package google 6 | 7 | import "testing" 8 | 9 | func TestSDKConfig(t *testing.T) { 10 | sdkConfigPath = func() (string, error) { 11 | return "testdata/gcloud", nil 12 | } 13 | 14 | tests := []struct { 15 | account string 16 | accessToken string 17 | err bool 18 | }{ 19 | {"", "bar_access_token", false}, 20 | {"foo@example.com", "foo_access_token", false}, 21 | {"bar@example.com", "bar_access_token", false}, 22 | {"baz@serviceaccount.example.com", "", true}, 23 | } 24 | for _, tt := range tests { 25 | c, err := NewSDKConfig(tt.account) 26 | if got, want := err != nil, tt.err; got != want { 27 | if !tt.err { 28 | t.Errorf("expected no error, got error: %v", tt.err, err) 29 | } else { 30 | t.Errorf("expected error, got none") 31 | } 32 | continue 33 | } 34 | if err != nil { 35 | continue 36 | } 37 | tok := c.initialToken 38 | if tok == nil { 39 | t.Errorf("expected token %q, got: nil", tt.accessToken) 40 | continue 41 | } 42 | if tok.AccessToken != tt.accessToken { 43 | t.Errorf("expected token %q, got: %q", tt.accessToken, tok.AccessToken) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/google/testdata/gcloud/properties: -------------------------------------------------------------------------------- 1 | [core] 2 | account = bar@example.com -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/internal/oauth2_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package internal contains support packages for oauth2 package. 6 | package internal 7 | 8 | import ( 9 | "reflect" 10 | "strings" 11 | "testing" 12 | ) 13 | 14 | func TestParseINI(t *testing.T) { 15 | tests := []struct { 16 | ini string 17 | want map[string]map[string]string 18 | }{ 19 | { 20 | `root = toor 21 | [foo] 22 | bar = hop 23 | ini = nin 24 | `, 25 | map[string]map[string]string{ 26 | "": map[string]string{"root": "toor"}, 27 | "foo": map[string]string{"bar": "hop", "ini": "nin"}, 28 | }, 29 | }, 30 | { 31 | `[empty] 32 | [section] 33 | empty= 34 | `, 35 | map[string]map[string]string{ 36 | "": map[string]string{}, 37 | "empty": map[string]string{}, 38 | "section": map[string]string{"empty": ""}, 39 | }, 40 | }, 41 | { 42 | `ignore 43 | [invalid 44 | =stuff 45 | ;comment=true 46 | `, 47 | map[string]map[string]string{ 48 | "": map[string]string{}, 49 | }, 50 | }, 51 | } 52 | for _, tt := range tests { 53 | result, err := ParseINI(strings.NewReader(tt.ini)) 54 | if err != nil { 55 | t.Errorf("ParseINI(%q) error %v, want: no error", tt.ini, err) 56 | continue 57 | } 58 | if !reflect.DeepEqual(result, tt.want) { 59 | t.Errorf("ParseINI(%q) = %#v, want: %#v", tt.ini, result, tt.want) 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/jwt/example_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package jwt_test 6 | 7 | import ( 8 | "golang.org/x/oauth2" 9 | "golang.org/x/oauth2/jwt" 10 | ) 11 | 12 | func ExampleJWTConfig() { 13 | conf := &jwt.Config{ 14 | Email: "xxx@developer.com", 15 | // The contents of your RSA private key or your PEM file 16 | // that contains a private key. 17 | // If you have a p12 file instead, you 18 | // can use `openssl` to export the private key into a pem file. 19 | // 20 | // $ openssl pkcs12 -in key.p12 -out key.pem -nodes 21 | // 22 | // It only supports PEM containers with no passphrase. 23 | PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."), 24 | Subject: "user@example.com", 25 | TokenURL: "https://provider.com/o/oauth2/token", 26 | } 27 | // Initiate an http.Client, the following GET request will be 28 | // authorized and authenticated on the behalf of user@example.com. 29 | client := conf.Client(oauth2.NoContext) 30 | client.Get("...") 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/linkedin/linkedin.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package linkedin provides constants for using OAuth2 to access LinkedIn. 6 | package linkedin 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is LinkedIn's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.linkedin.com/uas/oauth2/authorization", 15 | TokenURL: "https://www.linkedin.com/uas/oauth2/accessToken", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/odnoklassniki/odnoklassniki.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package odnoklassniki provides constants for using OAuth2 to access Odnoklassniki. 6 | package odnoklassniki 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is Odnoklassniki's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.odnoklassniki.ru/oauth/authorize", 15 | TokenURL: "https://api.odnoklassniki.ru/oauth/token.do", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/paypal/paypal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package paypal provides constants for using OAuth2 to access PayPal. 6 | package paypal 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is PayPal's OAuth 2.0 endpoint in live (production) environment. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize", 15 | TokenURL: "https://api.paypal.com/v1/identity/openidconnect/tokenservice", 16 | } 17 | 18 | // SandboxEndpoint is PayPal's OAuth 2.0 endpoint in sandbox (testing) environment. 19 | var SandboxEndpoint = oauth2.Endpoint{ 20 | AuthURL: "https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize", 21 | TokenURL: "https://api.sandbox.paypal.com/v1/identity/openidconnect/tokenservice", 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/token_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package oauth2 6 | 7 | import ( 8 | "testing" 9 | "time" 10 | ) 11 | 12 | func TestTokenExtra(t *testing.T) { 13 | type testCase struct { 14 | key string 15 | val interface{} 16 | want interface{} 17 | } 18 | const key = "extra-key" 19 | cases := []testCase{ 20 | {key: key, val: "abc", want: "abc"}, 21 | {key: key, val: 123, want: 123}, 22 | {key: key, val: "", want: ""}, 23 | {key: "other-key", val: "def", want: nil}, 24 | } 25 | for _, tc := range cases { 26 | extra := make(map[string]interface{}) 27 | extra[tc.key] = tc.val 28 | tok := &Token{raw: extra} 29 | if got, want := tok.Extra(key), tc.want; got != want { 30 | t.Errorf("Extra(%q) = %q; want %q", key, got, want) 31 | } 32 | } 33 | } 34 | 35 | func TestTokenExpiry(t *testing.T) { 36 | now := time.Now() 37 | cases := []struct { 38 | name string 39 | tok *Token 40 | want bool 41 | }{ 42 | {name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false}, 43 | {name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true}, 44 | } 45 | for _, tc := range cases { 46 | if got, want := tc.tok.expired(), tc.want; got != want { 47 | t.Errorf("expired (%q) = %v; want %v", tc.name, got, want) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/transport_test.go: -------------------------------------------------------------------------------- 1 | package oauth2 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | type tokenSource struct{ token *Token } 11 | 12 | func (t *tokenSource) Token() (*Token, error) { 13 | return t.token, nil 14 | } 15 | 16 | func TestTransportTokenSource(t *testing.T) { 17 | ts := &tokenSource{ 18 | token: &Token{ 19 | AccessToken: "abc", 20 | }, 21 | } 22 | tr := &Transport{ 23 | Source: ts, 24 | } 25 | server := newMockServer(func(w http.ResponseWriter, r *http.Request) { 26 | if r.Header.Get("Authorization") != "Bearer abc" { 27 | t.Errorf("Transport doesn't set the Authorization header from the fetched token") 28 | } 29 | }) 30 | defer server.Close() 31 | client := http.Client{Transport: tr} 32 | client.Get(server.URL) 33 | } 34 | 35 | func TestTokenValidNoAccessToken(t *testing.T) { 36 | token := &Token{} 37 | if token.Valid() { 38 | t.Errorf("Token should not be valid with no access token") 39 | } 40 | } 41 | 42 | func TestExpiredWithExpiry(t *testing.T) { 43 | token := &Token{ 44 | Expiry: time.Now().Add(-5 * time.Hour), 45 | } 46 | if token.Valid() { 47 | t.Errorf("Token should not be valid if it expired in the past") 48 | } 49 | } 50 | 51 | func newMockServer(handler func(w http.ResponseWriter, r *http.Request)) *httptest.Server { 52 | return httptest.NewServer(http.HandlerFunc(handler)) 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/golang.org/x/oauth2/vk/vk.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The oauth2 Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package vk provides constants for using OAuth2 to access VK.com. 6 | package vk 7 | 8 | import ( 9 | "golang.org/x/oauth2" 10 | ) 11 | 12 | // Endpoint is VK's OAuth 2.0 endpoint. 13 | var Endpoint = oauth2.Endpoint{ 14 | AuthURL: "https://oauth.vk.com/authorize", 15 | TokenURL: "https://oauth.vk.com/access_token", 16 | } 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/.gitignore: -------------------------------------------------------------------------------- 1 | _test 2 | _testmain.go 3 | _obj 4 | *~ 5 | *.6 6 | 6.out 7 | gorptest.bin 8 | tmp 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.1 4 | - tip 5 | 6 | services: 7 | - mysql 8 | - postgres 9 | - sqlite3 10 | 11 | before_script: 12 | - mysql -e "CREATE DATABASE gorptest;" 13 | - mysql -u root -e "GRANT ALL ON gorptest.* TO gorptest@localhost IDENTIFIED BY 'gorptest'" 14 | - psql -c "CREATE DATABASE gorptest;" -U postgres 15 | - psql -c "CREATE USER "gorptest" WITH SUPERUSER PASSWORD 'gorptest';" -U postgres 16 | - go get github.com/lib/pq 17 | - go get github.com/mattn/go-sqlite3 18 | - go get github.com/ziutek/mymysql/godrv 19 | - go get github.com/go-sql-driver/mysql 20 | 21 | script: ./test_all.sh 22 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012 James Cooper 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG = github.com/coopernurse/gorp 4 | GOFILES = gorp.go dialect.go 5 | 6 | include $(GOROOT)/src/Make.pkg -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/errors.go: -------------------------------------------------------------------------------- 1 | package gorp 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | // A non-fatal error, when a select query returns columns that do not exist 8 | // as fields in the struct it is being mapped to 9 | type NoFieldInTypeError struct { 10 | TypeName string 11 | MissingColNames []string 12 | } 13 | 14 | func (err *NoFieldInTypeError) Error() string { 15 | return fmt.Sprintf("gorp: No fields %+v in type %s", err.MissingColNames, err.TypeName) 16 | } 17 | 18 | // returns true if the error is non-fatal (ie, we shouldn't immediately return) 19 | func NonFatalError(err error) bool { 20 | switch err.(type) { 21 | case *NoFieldInTypeError: 22 | return true 23 | default: 24 | return false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/gorp.v1/test_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # on macs, you may need to: 4 | # export GOBUILDFLAG=-ldflags -linkmode=external 5 | 6 | set -e 7 | 8 | export GORP_TEST_DSN=gorptest/gorptest/gorptest 9 | export GORP_TEST_DIALECT=mysql 10 | go test $GOBUILDFLAG . 11 | 12 | export GORP_TEST_DSN=gorptest:gorptest@/gorptest 13 | export GORP_TEST_DIALECT=gomysql 14 | go test $GOBUILDFLAG . 15 | 16 | export GORP_TEST_DSN="user=gorptest password=gorptest dbname=gorptest sslmode=disable" 17 | export GORP_TEST_DIALECT=postgres 18 | go test $GOBUILDFLAG . 19 | 20 | export GORP_TEST_DSN=/tmp/gorptest.bin 21 | export GORP_TEST_DIALECT=sqlite 22 | go test $GOBUILDFLAG . 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/speter.net/go/exp/math/dec/inf/dec_go1_2_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.2 2 | 3 | package inf 4 | 5 | import ( 6 | "encoding" 7 | "encoding/json" 8 | "testing" 9 | ) 10 | 11 | var _ encoding.TextMarshaler = new(Dec) 12 | var _ encoding.TextUnmarshaler = new(Dec) 13 | 14 | type Obj struct { 15 | Val *Dec 16 | } 17 | 18 | func TestDecJsonMarshalUnmarshal(t *testing.T) { 19 | o := Obj{Val: NewDec(123, 2)} 20 | js, err := json.Marshal(o) 21 | if err != nil { 22 | t.Fatalf("json.Marshal(%v): got %v, want ok", o, err) 23 | } 24 | o2 := &Obj{} 25 | err = json.Unmarshal(js, o2) 26 | if err != nil { 27 | t.Fatalf("json.Unmarshal(%#q): got %v, want ok", js, err) 28 | } 29 | if o.Val.Scale() != o2.Val.Scale() || 30 | o.Val.UnscaledBig().Cmp(o2.Val.UnscaledBig()) != 0 { 31 | t.Fatalf("json.Unmarshal(json.Marshal(%v)): want %v, got %v", o, o, o2) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/speter.net/go/exp/math/dec/inf/dec_internal_test.go: -------------------------------------------------------------------------------- 1 | package inf 2 | 3 | import ( 4 | "math/big" 5 | "testing" 6 | ) 7 | 8 | var decQuoRemZZZ = []struct { 9 | z, x, y *Dec 10 | r *big.Rat 11 | srA, srB int 12 | }{ 13 | // basic examples 14 | {NewDec(1, 0), NewDec(2, 0), NewDec(2, 0), big.NewRat(0, 1), 0, 1}, 15 | {NewDec(15, 1), NewDec(3, 0), NewDec(2, 0), big.NewRat(0, 1), 0, 1}, 16 | {NewDec(1, 1), NewDec(1, 0), NewDec(10, 0), big.NewRat(0, 1), 0, 1}, 17 | {NewDec(0, 0), NewDec(2, 0), NewDec(3, 0), big.NewRat(2, 3), 1, 1}, 18 | {NewDec(0, 0), NewDec(2, 0), NewDec(6, 0), big.NewRat(1, 3), 1, 1}, 19 | {NewDec(1, 1), NewDec(2, 0), NewDec(12, 0), big.NewRat(2, 3), 1, 1}, 20 | 21 | // examples from the Go Language Specification 22 | {NewDec(1, 0), NewDec(5, 0), NewDec(3, 0), big.NewRat(2, 3), 1, 1}, 23 | {NewDec(-1, 0), NewDec(-5, 0), NewDec(3, 0), big.NewRat(-2, 3), -1, 1}, 24 | {NewDec(-1, 0), NewDec(5, 0), NewDec(-3, 0), big.NewRat(-2, 3), 1, -1}, 25 | {NewDec(1, 0), NewDec(-5, 0), NewDec(-3, 0), big.NewRat(2, 3), -1, -1}, 26 | } 27 | 28 | func TestDecQuoRem(t *testing.T) { 29 | for i, a := range decQuoRemZZZ { 30 | z, rA, rB := new(Dec), new(big.Int), new(big.Int) 31 | s := scaleQuoExact{}.Scale(a.x, a.y) 32 | z.quoRem(a.x, a.y, s, true, rA, rB) 33 | if a.z.Cmp(z) != 0 || a.r.Cmp(new(big.Rat).SetFrac(rA, rB)) != 0 { 34 | t.Errorf("#%d QuoRemZZZ got %v, %v, %v; expected %v, %v", i, z, rA, rB, a.z, a.r) 35 | } 36 | if a.srA != rA.Sign() || a.srB != rB.Sign() { 37 | t.Errorf("#%d QuoRemZZZ wrong signs, got %v, %v; expected %v, %v", i, rA.Sign(), rB.Sign(), a.srA, a.srB) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/speter.net/go/exp/math/dec/inf/example_test.go: -------------------------------------------------------------------------------- 1 | package inf_test 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | ) 7 | 8 | import "speter.net/go/exp/math/dec/inf" 9 | 10 | func ExampleDec_SetString() { 11 | d := new(inf.Dec) 12 | d.SetString("012345.67890") // decimal; leading 0 ignored; trailing 0 kept 13 | fmt.Println(d) 14 | // Output: 12345.67890 15 | } 16 | 17 | func ExampleDec_Scan() { 18 | // The Scan function is rarely used directly; 19 | // the fmt package recognizes it as an implementation of fmt.Scanner. 20 | d := new(inf.Dec) 21 | _, err := fmt.Sscan("184467440.73709551617", d) 22 | if err != nil { 23 | log.Println("error scanning value:", err) 24 | } else { 25 | fmt.Println(d) 26 | } 27 | // Output: 184467440.73709551617 28 | } 29 | 30 | func ExampleDec_QuoRound_scale2RoundDown() { 31 | // 10 / 3 is an infinite decimal; it has no exact Dec representation 32 | x, y := inf.NewDec(10, 0), inf.NewDec(3, 0) 33 | // use 2 digits beyond the decimal point, round towards 0 34 | z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundDown) 35 | fmt.Println(z) 36 | // Output: 3.33 37 | } 38 | 39 | func ExampleDec_QuoRound_scale2RoundCeil() { 40 | // -42 / 400 is an finite decimal with 3 digits beyond the decimal point 41 | x, y := inf.NewDec(-42, 0), inf.NewDec(400, 0) 42 | // use 2 digits beyond decimal point, round towards positive infinity 43 | z := new(inf.Dec).QuoRound(x, y, 2, inf.RoundCeil) 44 | fmt.Println(z) 45 | // Output: -0.10 46 | } 47 | 48 | func ExampleDec_QuoExact_ok() { 49 | // 1 / 25 is a finite decimal; it has exact Dec representation 50 | x, y := inf.NewDec(1, 0), inf.NewDec(25, 0) 51 | z := new(inf.Dec).QuoExact(x, y) 52 | fmt.Println(z) 53 | // Output: 0.04 54 | } 55 | 56 | func ExampleDec_QuoExact_fail() { 57 | // 1 / 3 is an infinite decimal; it has no exact Dec representation 58 | x, y := inf.NewDec(1, 0), inf.NewDec(3, 0) 59 | z := new(inf.Dec).QuoExact(x, y) 60 | fmt.Println(z) 61 | // Output: 62 | } 63 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: cmd docker 2 | 3 | cmd: 4 | godep go build -o build/tugboat ./cmd/tugboat 5 | godep go build -o build/fake ./cmd/fake 6 | 7 | docker: 8 | docker build --no-cache -t remind101/tugboat . 9 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: tugboat server 2 | -------------------------------------------------------------------------------- /bin/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | echo "hosts: files dns" >> /etc/nsswitch.conf 6 | echo "@edge-community http://dl-4.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories 7 | packages="curl git go@edge-community" 8 | 9 | apk add --update $packages 10 | 11 | GOPATH=/go go get github.com/tools/godep 12 | cd /go/src/github.com/remind101/tugboat 13 | PATH="/go/bin:$PATH" GOPATH=/go godep go install ./cmd/... 14 | mv /go/bin/tugboat /bin 15 | 16 | mkdir -p /var/run/tugboat 17 | cp Procfile /var/run/tugboat 18 | cp -r ./migrations /var/run/tugboat 19 | cp -r ./frontend /var/run/tugboat 20 | 21 | apk del curl git go 22 | rm -rf /var/cache/apk/* /go /var/run/tugboat/frontend/node_modules 23 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | timezone: America/Los_Angeles 3 | services: 4 | - postgresql 5 | 6 | checkout: 7 | post: 8 | - rm -rf ~/.go_workspace/src/github.com/remind101 9 | - mkdir -p ~/.go_workspace/src/github.com/remind101 10 | - cp -R ~/tugboat ~/.go_workspace/src/github.com/remind101/tugboat 11 | 12 | dependencies: 13 | pre: 14 | - go install -a -race std 15 | - go get github.com/tools/godep 16 | - createdb tugboat 17 | - cd ~/.go_workspace/src/github.com/remind101/tugboat && godep go install ./cmd/... 18 | - cd ~/.go_workspace/src/github.com/remind101/tugboat && tugboat migrate 19 | 20 | 21 | test: 22 | override: 23 | - cd ~/.go_workspace/src/github.com/remind101/tugboat && make cmd 24 | - cd ~/.go_workspace/src/github.com/remind101/tugboat && godep go test -race ./... 25 | -------------------------------------------------------------------------------- /cmd/fake/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "flag" 7 | "io" 8 | "io/ioutil" 9 | "log" 10 | "os" 11 | 12 | "github.com/remind101/tugboat" 13 | "golang.org/x/net/context" 14 | ) 15 | 16 | var ( 17 | payload = flag.String("payload", "tests/api/test-fixtures/deployment.json", "") 18 | secret = flag.String("secret", "", "") 19 | url = flag.String("url", "http://eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQcm92aWRlciI6ImZha2UifQ.zmy2Wq7Zbol7N1X-R7WX5R4E2i7uH_Arv7FRR2UwnDE:@localhost:8080", "") 20 | fail = flag.Bool("fail", false, "Whether the deployment should fail with an error") 21 | ) 22 | 23 | func main() { 24 | flag.Parse() 25 | 26 | if err := deploy(); err != nil { 27 | log.Fatal(err) 28 | } 29 | } 30 | 31 | func deploy() error { 32 | raw, err := ioutil.ReadFile(*payload) 33 | if err != nil { 34 | return err 35 | } 36 | 37 | c := tugboat.NewClient(nil) 38 | c.URL = *url 39 | 40 | opts, err := tugboat.NewDeployOptsFromReader(bytes.NewReader(raw)) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | c.Deploy(context.Background(), opts, tugboat.ProviderFunc(perform)) 46 | 47 | return nil 48 | } 49 | 50 | func perform(ctx context.Context, d *tugboat.Deployment, w io.Writer) error { 51 | if _, err := io.Copy(w, bufio.NewReader(os.Stdin)); err != nil { 52 | return err 53 | } 54 | 55 | if *fail { 56 | return tugboat.ErrFailed 57 | } 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /cmd/tugboat/migrate.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | 7 | "github.com/codegangsta/cli" 8 | "github.com/remind101/tugboat" 9 | ) 10 | 11 | var cmdMigrate = cli.Command{ 12 | Name: "migrate", 13 | ShortName: "m", 14 | Usage: "Migrate the database", 15 | Action: runMigrate, 16 | Flags: []cli.Flag{ 17 | flagDB, 18 | cli.StringFlag{ 19 | Name: "db.migrations", 20 | Value: "./migrations", 21 | Usage: "Path to the directory containing migrations.", 22 | }, 23 | }, 24 | } 25 | 26 | func runMigrate(c *cli.Context) { 27 | db := c.String("db.url") 28 | path := c.String("db.migrations") 29 | 30 | errors, ok := tugboat.Migrate(db, path) 31 | if !ok { 32 | log.Fatal(errors) 33 | } 34 | 35 | fmt.Println("Up to date") 36 | } 37 | -------------------------------------------------------------------------------- /cmd/tugboat/tokens.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "log" 7 | "os" 8 | "text/template" 9 | 10 | "github.com/codegangsta/cli" 11 | "github.com/remind101/tugboat" 12 | ) 13 | 14 | var inspectTemplate = `Provider: {{.Provider}} 15 | Token: {{.Token}}` 16 | 17 | var cmdTokens = cli.Command{ 18 | Name: "tokens", 19 | Subcommands: []cli.Command{ 20 | { 21 | Name: "create", 22 | Usage: "Creates a new token for an external provider. External providers should use this token as the basic auth user when creating deployments.", 23 | Action: runTokensCreate, 24 | Flags: []cli.Flag{ 25 | flagDB, 26 | flagProviderSecret, 27 | }, 28 | }, 29 | { 30 | Name: "inspect", 31 | Usage: "Inspects a token", 32 | Action: runTokensInspect, 33 | Flags: []cli.Flag{ 34 | flagDB, 35 | flagProviderSecret, 36 | cli.StringFlag{ 37 | Name: "template", 38 | Value: inspectTemplate, 39 | }, 40 | }, 41 | }, 42 | }, 43 | } 44 | 45 | func runTokensCreate(c *cli.Context) { 46 | tug, err := newTugboat(c) 47 | if err != nil { 48 | log.Fatal(err) 49 | } 50 | 51 | provider := c.Args().First() 52 | 53 | if provider == "" { 54 | fmt.Fprintf(os.Stderr, "You must specify a provider name.\n") 55 | os.Exit(-1) 56 | } 57 | 58 | token := &tugboat.Token{Provider: provider} 59 | if err := tug.TokensCreate(token); err != nil { 60 | log.Fatal(err) 61 | } 62 | 63 | fmt.Println(token.Token) 64 | } 65 | 66 | func runTokensInspect(c *cli.Context) { 67 | tug, err := newTugboat(c) 68 | if err != nil { 69 | log.Fatal(err) 70 | } 71 | 72 | token := c.Args().First() 73 | 74 | if token == "" { 75 | fmt.Fprintf(os.Stderr, "Please provide a token.") 76 | os.Exit(-1) 77 | } 78 | 79 | t, err := tug.TokensFind(token) 80 | if err != nil { 81 | log.Fatal(err) 82 | } 83 | 84 | tmpl := template.Must(template.New("token").Parse(c.String("template"))) 85 | if err := tmpl.Execute(os.Stdout, t); err != nil { 86 | log.Fatal(err) 87 | } 88 | io.WriteString(os.Stdout, "\n") 89 | } 90 | -------------------------------------------------------------------------------- /db.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "database/sql" 5 | "net/url" 6 | 7 | _ "github.com/lib/pq" 8 | "gopkg.in/gorp.v1" 9 | ) 10 | 11 | type db struct { 12 | *gorp.DbMap 13 | db *sql.DB 14 | } 15 | 16 | func dialDB(uri string) (*db, error) { 17 | u, err := url.Parse(uri) 18 | if err != nil { 19 | return nil, err 20 | } 21 | 22 | conn, err := sql.Open(u.Scheme, uri) 23 | if err != nil { 24 | return nil, err 25 | } 26 | 27 | dbmap := &gorp.DbMap{Db: conn, Dialect: gorp.PostgresDialect{}} 28 | db := &db{DbMap: dbmap, db: conn} 29 | 30 | db.DbMap.AddTableWithName(Deployment{}, "deployments").SetKeys(true, "ID") 31 | db.DbMap.AddTableWithName(LogLine{}, "logs").SetKeys(true, "ID") 32 | 33 | return db, nil 34 | } 35 | -------------------------------------------------------------------------------- /deployments_test.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | ) 7 | 8 | func TestDeploymentStarted(t *testing.T) { 9 | d := &Deployment{} 10 | d.Started("fake") 11 | 12 | if got, want := d.Status, StatusStarted; got != want { 13 | t.Fatalf("Status => %s; want %s", got, want) 14 | } 15 | 16 | if got, want := d.Provider, "fake"; got != want { 17 | t.Fatalf("Provider => %s; want %s", got, want) 18 | } 19 | 20 | if d.StartedAt == nil { 21 | t.Fatalf("expected StartedAt to not be nil") 22 | } 23 | } 24 | 25 | func TestDeploymentFailed(t *testing.T) { 26 | d := &Deployment{Status: StatusPending} 27 | d.Failed() 28 | 29 | if got, want := d.Status, StatusFailed; got != want { 30 | t.Fatalf("Status => %s; want %s", got, want) 31 | } 32 | 33 | if got, want := d.prevStatus, StatusPending; got != want { 34 | t.Fatalf("prevStatus => %s; want %s", got, want) 35 | } 36 | 37 | if d.CompletedAt == nil { 38 | t.Fatalf("expected CompletedAt to not be nil") 39 | } 40 | } 41 | 42 | func TestDeploymentSucceeded(t *testing.T) { 43 | d := &Deployment{Status: StatusPending} 44 | d.Succeeded() 45 | 46 | if got, want := d.Status, StatusSucceeded; got != want { 47 | t.Fatalf("Status => %s; want %s", got, want) 48 | } 49 | 50 | if got, want := d.prevStatus, StatusPending; got != want { 51 | t.Fatalf("prevStatus => %s; want %s", got, want) 52 | } 53 | 54 | if d.CompletedAt == nil { 55 | t.Fatalf("expected CompletedAt to not be nil") 56 | } 57 | } 58 | 59 | func TestDeploymentErrored(t *testing.T) { 60 | d := &Deployment{Status: StatusPending} 61 | d.Errored(errors.New("boom")) 62 | 63 | if got, want := d.Error, "boom"; got != want { 64 | t.Fatalf("Error => %s; want %s", got, want) 65 | } 66 | 67 | if got, want := d.Status, StatusErrored; got != want { 68 | t.Fatalf("Status => %s; want %s", got, want) 69 | } 70 | 71 | if got, want := d.prevStatus, StatusPending; got != want { 72 | t.Fatalf("prevStatus => %s; want %s", got, want) 73 | } 74 | 75 | if d.CompletedAt == nil { 76 | t.Fatalf("expected CompletedAt to not be nil") 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | tugboat: 2 | build: ./ 3 | env_file: .env 4 | ports: 5 | - "8080:8080" 6 | environment: 7 | DATABASE_URL: postgres://postgres:postgres@postgres/postgres?sslmode=disable 8 | links: 9 | - postgres 10 | postgres: 11 | image: postgres 12 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | This is the source for the AngularJS frontend. 2 | -------------------------------------------------------------------------------- /frontend/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Tugboat - We'll do it live! 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /frontend/frontend.go: -------------------------------------------------------------------------------- 1 | package frontend 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "io/ioutil" 7 | "net/http" 8 | "text/template" 9 | 10 | "github.com/codegangsta/negroni" 11 | ) 12 | 13 | var ( 14 | // DefaultDirectory is the path to the compiled frontend. 15 | DefaultDirectory = "frontend/dist" 16 | 17 | // DefaultIndex is the name of the fallback file to render. 18 | DefaultIndex = "/index.html" 19 | ) 20 | 21 | // Handler is an http.Handler that serves the frontend. 22 | type Handler struct { 23 | PusherKey string 24 | 25 | Dir string 26 | Index string 27 | static *negroni.Static 28 | 29 | index []byte 30 | } 31 | 32 | // New returns a new Handler instance. 33 | func New(dir string) *Handler { 34 | if dir == "" { 35 | dir = DefaultDirectory 36 | } 37 | 38 | s := negroni.NewStatic(http.Dir(dir)) 39 | s.IndexFile = "" 40 | return &Handler{ 41 | Dir: dir, 42 | Index: DefaultIndex, 43 | static: s, 44 | } 45 | } 46 | 47 | func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 48 | h.static.ServeHTTP(w, r, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 49 | io.Copy(w, h.indexReader()) 50 | })) 51 | } 52 | 53 | func (h *Handler) indexReader() io.Reader { 54 | if h.index != nil { 55 | return bytes.NewReader(h.index) 56 | } 57 | 58 | raw, err := ioutil.ReadFile(h.Dir + h.Index) 59 | if err != nil { 60 | panic(err) 61 | } 62 | 63 | tmpl, err := template.New("index").Parse(string(raw)) 64 | if err != nil { 65 | panic(err) 66 | } 67 | 68 | data := struct { 69 | PusherKey string 70 | }{ 71 | PusherKey: h.PusherKey, 72 | } 73 | 74 | b := new(bytes.Buffer) 75 | if err := tmpl.Execute(b, data); err != nil { 76 | panic(err) 77 | } 78 | 79 | h.index = b.Bytes() 80 | 81 | return bytes.NewReader(h.index) 82 | } 83 | -------------------------------------------------------------------------------- /frontend/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | concat = require('gulp-concat'), 3 | uglify = require('gulp-uglify'), 4 | sass = require('gulp-sass'), 5 | html2js = require('gulp-ng-html2js'), 6 | merge = require('merge-stream'); 7 | 8 | var paths = { 9 | dest: 'dist', 10 | scripts: 'javascripts/**/*.js', 11 | stylesheets: 'stylesheets/**/*.scss', 12 | templates: 'templates/**/*.html' 13 | }; 14 | 15 | gulp.task('sass', function() { 16 | return gulp.src(paths.stylesheets) 17 | .pipe(sass()) 18 | .pipe(gulp.dest(paths.dest)) 19 | }); 20 | 21 | gulp.task('stylesheets', ['sass']); 22 | 23 | gulp.task('javascripts', function() { 24 | var templates = gulp.src(paths.templates) 25 | .pipe(html2js({ moduleName: 'templates' })); 26 | 27 | var scripts = gulp.src(paths.scripts); 28 | 29 | return merge(scripts, templates) 30 | .pipe(concat('app.js')) 31 | .pipe(gulp.dest(paths.dest)); 32 | }); 33 | 34 | gulp.task('html', function() { 35 | return gulp.src('index.html') 36 | .pipe(gulp.dest(paths.dest)); 37 | }); 38 | 39 | gulp.task('watch', ['javascripts', 'stylesheets', 'html'], function() { 40 | gulp.watch(paths.scripts, ['javascripts']); 41 | gulp.watch(paths.templates, ['javascripts']); 42 | gulp.watch(paths.stylesheets, ['stylesheets']); 43 | gulp.watch('index.html', ['html']); 44 | }); 45 | 46 | gulp.task('default', ['stylesheets', 'javascripts', 'html']); 47 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Tugboat - We'll do it live! 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /frontend/javascripts/app.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | 4 | var module = angular.module('app', [ 5 | 'ng', 6 | 'ngSanitize', 7 | 'ui.router', 8 | 'templates', 9 | 'app.directives', 10 | 'app.services', 11 | 'app.filters', 12 | 'app.controllers', 13 | 'angularMoment' 14 | ]); 15 | 16 | module.config(function($locationProvider, $stateProvider) { 17 | $locationProvider.html5Mode(true); 18 | 19 | $stateProvider 20 | .state('app', { 21 | 'abstract': true, 22 | views: { 23 | header: { templateUrl: 'header.html' }, 24 | content: { templateUrl: 'content.html' } 25 | } 26 | }) 27 | 28 | .state('app.jobs', { 29 | 'abstract': true, 30 | templateUrl: 'jobs.html' 31 | }) 32 | 33 | .state('app.jobs.list', { 34 | url: '/', 35 | controller: 'JobsListCtrl', 36 | templateUrl: 'jobs/list.html', 37 | resolve: { 38 | jobs: function(Job) { 39 | return Job.all(); 40 | } 41 | } 42 | }) 43 | 44 | .state('app.jobs.detail', { 45 | url: '/deploys/:jobId', 46 | controller: 'JobsDetailCtrl', 47 | templateUrl: 'jobs/detail.html', 48 | resolve: { 49 | job: function($stateParams, Job) { 50 | return Job.find($stateParams.jobId); 51 | } 52 | } 53 | }); 54 | }); 55 | 56 | module.config(function($httpProvider) { 57 | $httpProvider.defaults.headers.common = { 58 | 'Accept': 'application/vnd.tugboat+json; version=1' 59 | } 60 | $httpProvider.defaults.withCredentials = true; 61 | delete $httpProvider.defaults.headers.common["X-Requested-With"]; 62 | }); 63 | 64 | module.run(function($rootScope, $log, $state) { 65 | $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { 66 | $log.error(error); 67 | $state.go('app.jobs.list'); 68 | }); 69 | }); 70 | 71 | })(angular); 72 | -------------------------------------------------------------------------------- /frontend/javascripts/controllers.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | 4 | var module = angular.module('app.controllers', [ 5 | 'ng' 6 | ]); 7 | 8 | module.controller('JobsListCtrl', function($scope, jobs) { 9 | $scope.jobs = jobs; 10 | }); 11 | 12 | module.controller('JobsDetailCtrl', function($scope, $state, job, jobEvents) { 13 | $scope.job = jobEvents.subscribe($scope, job); 14 | }); 15 | 16 | })(angular); 17 | -------------------------------------------------------------------------------- /frontend/javascripts/directives.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | 4 | var module = angular.module('app.directives', [ 5 | 'ng' 6 | ]); 7 | 8 | /** 9 | * A directive for building a css3 spinner. 10 | */ 11 | module.directive('spinner', function() { 12 | return { 13 | restrict: 'C', 14 | link: function(scope, elem) { 15 | function addRect(i) { 16 | elem.append('
'); 17 | } 18 | 19 | _(4).times(addRect); 20 | } 21 | }; 22 | }); 23 | 24 | module.directive('sticky', function($document, $window) { 25 | var padding = 100; 26 | 27 | return { 28 | restrict: 'A', 29 | link: function(scope, elem, attrs) { 30 | var $doc = $window.$($document), 31 | $win = $window.$($window); 32 | 33 | scope.$watch(attrs.sticky, function() { 34 | var sticky = $doc.scrollTop() + $win.height() >= $doc.height() - padding; 35 | 36 | if (sticky) { 37 | $doc.scrollTop($doc.height()); 38 | } 39 | }); 40 | } 41 | } 42 | }); 43 | 44 | /** 45 | * A directive that for showing environment variables. 46 | */ 47 | module.directive('environmentVariables', function($compile) { 48 | return { 49 | restrict: 'A', 50 | scope: { environmentVariables: '=' }, 51 | link: function(scope, elem) { 52 | _.each(scope.environmentVariables, function(value, key) { 53 | elem.append($compile('')(scope)); 54 | }); 55 | } 56 | }; 57 | }); 58 | 59 | module.directive('environmentVariable', function() { 60 | return { 61 | restrict: 'EA', 62 | scope: { var: '@', value: '@' }, 63 | template: '
=
' 64 | }; 65 | }); 66 | 67 | })(angular); 68 | -------------------------------------------------------------------------------- /frontend/javascripts/filters.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | 4 | var module = angular.module('app.filters', [ 5 | 'ng' 6 | ]); 7 | 8 | module.filter('ansi', function($window, $sce) { 9 | var ansi_up = $window.ansi_up, 10 | ansi_to_html = ansi_up.ansi_to_html, 11 | escape_for_html = ansi_up.escape_for_html; 12 | 13 | return function(input) { 14 | return $sce.trustAsHtml(ansi_to_html(escape_for_html(input))); 15 | }; 16 | }); 17 | 18 | })(angular); 19 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tugbt", 3 | "repository": "tugbt/tugbt", 4 | "scripts": { 5 | "build": "./node_modules/.bin/gulp" 6 | }, 7 | "devDependencies": { 8 | "gulp": "~3.8.6", 9 | "gulp-rev": "~0.4.2", 10 | "gulp-concat": "~2.3.3", 11 | "gulp-uglify": "~0.3.1", 12 | "gulp-sass": "~2.3.2", 13 | "gulp-ng-html2js": "~0.1.7", 14 | "merge-stream": "~0.1.5" 15 | }, 16 | "engines": { 17 | "node": ">=0.8.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/stylesheets/_job.scss: -------------------------------------------------------------------------------- 1 | .job__header { 2 | margin: 40px; 3 | text-align: center; 4 | 5 | .is-queued { 6 | color: #999; 7 | 8 | .spinner > div { 9 | background-color: #999; 10 | } 11 | } 12 | 13 | .is-started { 14 | color: #3498db; 15 | 16 | .spinner > div { 17 | background-color: #3498db; 18 | } 19 | } 20 | 21 | .is-failed, .is-errored { 22 | color: #e74c3c; 23 | } 24 | 25 | .spinner { 26 | margin-left: -10px; 27 | } 28 | } 29 | 30 | .job__destination { 31 | color: #999; 32 | font-size: 20px; 33 | } 34 | 35 | .job__log { 36 | padding: 10px; 37 | color: #f1f1f1; 38 | background: #000; 39 | font-family: monospace; 40 | font-size: 12px; 41 | line-height: 18px; 42 | white-space: pre-wrap; 43 | word-break: break-work; 44 | border-radius: 5px; 45 | margin-bottom: 40px; 46 | } 47 | 48 | .job__not-started { 49 | padding: 60px; 50 | text-align: center; 51 | border-radius: 5px; 52 | border: 4px dashed #eee; 53 | } 54 | -------------------------------------------------------------------------------- /frontend/stylesheets/_spinner.scss: -------------------------------------------------------------------------------- 1 | .spinner { 2 | display: inline-block; 3 | width: 50px; 4 | height: 30px; 5 | text-align: center; 6 | font-size: 10px; 7 | } 8 | 9 | .spinner > div { 10 | background-color: #3498db; 11 | height: 100%; 12 | width: 6px; 13 | display: inline-block; 14 | 15 | -webkit-animation: stretchdelay 1.2s infinite ease-in-out; 16 | animation: stretchdelay 1.2s infinite ease-in-out; 17 | } 18 | 19 | .spinner .rect2 { 20 | -webkit-animation-delay: -1.1s; 21 | animation-delay: -1.1s; 22 | } 23 | 24 | .spinner .rect3 { 25 | -webkit-animation-delay: -1.0s; 26 | animation-delay: -1.0s; 27 | } 28 | 29 | .spinner .rect4 { 30 | -webkit-animation-delay: -0.9s; 31 | animation-delay: -0.9s; 32 | } 33 | 34 | .spinner .rect5 { 35 | -webkit-animation-delay: -0.8s; 36 | animation-delay: -0.8s; 37 | } 38 | 39 | @-webkit-keyframes stretchdelay { 40 | 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 41 | 20% { -webkit-transform: scaleY(1.0) } 42 | } 43 | 44 | @keyframes stretchdelay { 45 | 0%, 40%, 100% { 46 | transform: scaleY(0.4); 47 | -webkit-transform: scaleY(0.4); 48 | } 20% { 49 | transform: scaleY(1.0); 50 | -webkit-transform: scaleY(1.0); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /frontend/stylesheets/app.scss: -------------------------------------------------------------------------------- 1 | @import 2 | 'spinner', 3 | 'job'; 4 | 5 | #loading { 6 | text-align: center; 7 | padding-top: 40px; 8 | 9 | img { 10 | display: block; 11 | margin: 0 auto; 12 | } 13 | 14 | .spinner > div { 15 | background-color: #000; 16 | } 17 | } 18 | 19 | #header .navbar-right { 20 | margin-right: 0; 21 | 22 | .user a { 23 | display: inline-block; 24 | } 25 | 26 | .user .gravatar { 27 | border-radius: 100px; 28 | max-width: 45px; 29 | margin-top: -3px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /frontend/templates/content.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /frontend/templates/header.html: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /frontend/templates/jobs.html: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /frontend/templates/jobs/detail.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | 5 |
6 | Queued 7 | Deploying 8 |
9 | Deployed 10 | Failed 11 | Errored 12 |

13 |

14 | 15 | ⇢ 16 | 17 |

18 |
19 |
20 | Hang Tight! 21 | Your logs should be showing up shortly 22 |
23 |
24 |
25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /frontend/templates/jobs/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
#UserRepoRefEnvironmentProviderStatusStarted AtCompleted At
19 | 20 |
32 | -------------------------------------------------------------------------------- /logs_test.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func TestLogWriter(t *testing.T) { 11 | tests := []struct { 12 | in io.Reader 13 | out []string 14 | }{ 15 | { 16 | strings.NewReader(`-----> Fetching custom git buildpack... done 17 | -----> Go app detected 18 | -----> Using go1.3 19 | -----> Running: godep go install -tags heroku ./... 20 | -----> Discovering process types 21 | Procfile declares types -> web 22 | 23 | -----> Compressing... done, 1.6MB 24 | -----> Launching... done, v6 25 | https://acme-inc.herokuapp.com/ deployed to Heroku 26 | `), 27 | []string{ 28 | "-----> Fetching custom git buildpack... done\n", 29 | "-----> Go app detected\n", 30 | "-----> Using go1.3\n", 31 | "-----> Running: godep go install -tags heroku ./...\n", 32 | "-----> Discovering process types\n", 33 | " Procfile declares types -> web\n", 34 | "\n", 35 | "-----> Compressing... done, 1.6MB\n", 36 | "-----> Launching... done, v6\n", 37 | " https://acme-inc.herokuapp.com/ deployed to Heroku\n", 38 | "", 39 | }, 40 | }, 41 | { 42 | bytes.NewReader([]byte{ 43 | 'h', 'e', 'l', 'l', 'o', '\n', 44 | 0x00, 45 | 'w', 'o', 'r', 'l', 'd', 46 | }), 47 | []string{ 48 | "hello\n", 49 | "world", 50 | }, 51 | }, 52 | } 53 | 54 | for _, tt := range tests { 55 | var lines []*LogLine 56 | 57 | w := &logWriter{ 58 | createLogLine: func(l *LogLine) error { 59 | lines = append(lines, l) 60 | return nil 61 | }, 62 | deploymentID: "1", 63 | } 64 | 65 | if _, err := io.Copy(w, tt.in); err != nil { 66 | t.Fatal(err) 67 | } 68 | 69 | if got, want := len(lines), len(tt.out); got != want { 70 | t.Fatalf("len(lines) => %d; want %d", got, want) 71 | } 72 | 73 | for i := 0; i < len(lines); i++ { 74 | if got, want := lines[i].Text, tt.out[i]; got != want { 75 | t.Errorf("Line #%d => %q; want %q", i, got, want) 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /migrations/0001_initial_schema.down.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE logs; 2 | DROP TABLE deployments; 3 | -------------------------------------------------------------------------------- /migrations/0001_initial_schema.up.sql: -------------------------------------------------------------------------------- 1 | CREATE EXTENSION IF NOT EXISTS hstore; 2 | CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; 3 | 4 | CREATE TABLE deployments ( 5 | id uuid NOT NULL DEFAULT uuid_generate_v4() primary key, 6 | status text NOT NULL, 7 | github_id int NOT NULL, 8 | sha text NOT NULL, 9 | ref text NOT NULL, 10 | environment text NOT NULL, 11 | description text NOT NULL, 12 | repo text NOT NULL, 13 | provider text NOT NULL, 14 | error text NOT NULL, 15 | created_at timestamp without time zone default (now() at time zone 'utc') NOT NULL, 16 | started_at timestamp without time zone, 17 | completed_at timestamp without time zone 18 | ); 19 | 20 | CREATE TABLE logs ( 21 | id uuid NOT NULL DEFAULT uuid_generate_v4() primary key, 22 | deployment_id uuid NOT NULL references deployments(id) ON DELETE CASCADE, 23 | text text NOT NULL, 24 | at timestamp without time zone NOT NULL 25 | ); 26 | 27 | CREATE INDEX index_deployments_on_github_id ON deployments USING btree (github_id); 28 | CREATE INDEX index_deployments_on_created_at ON deployments USING btree (created_at); 29 | CREATE INDEX index_logs_on_at ON logs USING btree (at); 30 | -------------------------------------------------------------------------------- /migrations/0002_add_user_column.down.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE deployments DROP COLUMN login text; 2 | -------------------------------------------------------------------------------- /migrations/0002_add_user_column.up.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE deployments ADD COLUMN login text NOT NULL; 2 | -------------------------------------------------------------------------------- /pkg/README.md: -------------------------------------------------------------------------------- 1 | pkg/ is a collection of utility packages used by the Tugboat project without being specific to its internals. 2 | 3 | Utility packages are kept separate from the tugboat core codebase to keep it as small and concise as possible. If some utilities grow larger and their APIs stabilize, they may be moved to their own repository, to facilitate re-use by other projects. However that is not the priority. 4 | 5 | The directory pkg is named after the same directory in the Docker and camlistore projects. 6 | -------------------------------------------------------------------------------- /pkg/hooker/hooker.go: -------------------------------------------------------------------------------- 1 | // package hooker can generate github webhooks. It's only real use is for 2 | // testing endpoints that handle github webhooks. 3 | package hooker 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "fmt" 9 | "io" 10 | "io/ioutil" 11 | "net/http" 12 | 13 | "github.com/ejholmes/hookshot" 14 | ) 15 | 16 | type Client struct { 17 | // Secret is a secret to sign request bodies with. 18 | Secret string 19 | 20 | // URL is the url to make requests against. 21 | URL string 22 | 23 | client *http.Client 24 | } 25 | 26 | func NewClient(c *http.Client) *Client { 27 | if c == nil { 28 | c = http.DefaultClient 29 | } 30 | 31 | return &Client{ 32 | client: c, 33 | } 34 | } 35 | 36 | func (c *Client) Trigger(event string, v interface{}) (*http.Response, error) { 37 | b := new(bytes.Buffer) 38 | 39 | switch v := v.(type) { 40 | case io.Reader: 41 | if _, err := io.Copy(b, v); err != nil { 42 | return nil, err 43 | } 44 | default: 45 | if err := json.NewEncoder(b).Encode(v); err != nil { 46 | return nil, err 47 | } 48 | } 49 | 50 | req, err := http.NewRequest("POST", c.URL, b) 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | req.Header.Set("X-GitHub-Event", event) 56 | req.Header.Set("X-Hub-Signature", fmt.Sprintf("sha1=%s", hookshot.Signature(b.Bytes(), c.Secret))) 57 | 58 | return c.Do(req) 59 | } 60 | 61 | func (c *Client) Do(req *http.Request) (*http.Response, error) { 62 | resp, err := c.client.Do(req) 63 | if err != nil { 64 | return resp, err 65 | } 66 | 67 | if resp.StatusCode/100 != 2 { 68 | raw, err := ioutil.ReadAll(resp.Body) 69 | if err != nil { 70 | return resp, err 71 | } 72 | resp.Body.Close() 73 | 74 | return resp, fmt.Errorf("hooker: request failed with status %d: %s", resp.StatusCode, raw) 75 | } 76 | 77 | return resp, err 78 | } 79 | -------------------------------------------------------------------------------- /pkg/hooker/hooker_test.go: -------------------------------------------------------------------------------- 1 | package hooker 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "net/http" 7 | "net/http/httptest" 8 | "testing" 9 | 10 | "github.com/ejholmes/hookshot" 11 | ) 12 | 13 | func TestHooker(t *testing.T) { 14 | h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 | raw, err := ioutil.ReadAll(r.Body) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | if got, want := string(raw), `{"Data":"foo"}`+"\n"; got != want { 21 | t.Fatalf("Body => %s; want %s", got, want) 22 | } 23 | 24 | io.WriteString(w, "ok\n") 25 | }) 26 | s := httptest.NewServer(hookshot.Authorize(h, "secret")) 27 | defer s.Close() 28 | 29 | c := NewClient(nil) 30 | c.Secret = "secret" 31 | c.URL = s.URL 32 | 33 | body := struct { 34 | Data string 35 | }{ 36 | Data: "foo", 37 | } 38 | resp, err := c.Trigger("ping", &body) 39 | if err != nil { 40 | t.Fatal(err) 41 | } 42 | 43 | raw, err := ioutil.ReadAll(resp.Body) 44 | if err != nil { 45 | t.Fatal(err) 46 | } 47 | 48 | if got, want := string(raw), "ok\n"; got != want { 49 | t.Fatalf("Response => %s; want %s", got, want) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pkg/pusherauth/auth.go: -------------------------------------------------------------------------------- 1 | // package pusherauth is a package for generating pusher authentication 2 | // signatures. See https://pusher.com/docs/authenticating_users and 3 | // https://pusher.com/docs/auth_signatures. 4 | package pusherauth 5 | 6 | import ( 7 | "crypto/hmac" 8 | "crypto/sha256" 9 | "encoding/json" 10 | "fmt" 11 | "net/http" 12 | ) 13 | 14 | // Sign generates a suitable HMAC signature of the socket and channel. 15 | func Sign(secret []byte, socketID, channel string) string { 16 | m := fmt.Sprintf("%s:%s", socketID, channel) 17 | mac := hmac.New(sha256.New, secret) 18 | mac.Write([]byte(m)) 19 | return fmt.Sprintf("%x", mac.Sum(nil)) 20 | } 21 | 22 | // Handler is an http.Handler that will respond with a pusher auth string. 23 | type Handler struct { 24 | // Pusher application key. 25 | Key string 26 | 27 | // Pusher secret, used to sign the auth payload. 28 | Secret []byte 29 | } 30 | 31 | func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 32 | socketID := r.FormValue("socket_id") 33 | channel := r.FormValue("channel_name") 34 | 35 | sig := Sign(h.Secret, socketID, channel) 36 | 37 | json.NewEncoder(w).Encode(map[string]string{ 38 | "auth": fmt.Sprintf("%s:%s", h.Key, sig), 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/pusherauth/auth_test.go: -------------------------------------------------------------------------------- 1 | package pusherauth 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | const testSecret = "7ad3773142a6692b25b8" 10 | 11 | func TestSign(t *testing.T) { 12 | tests := []struct { 13 | socketID string 14 | channel string 15 | 16 | signature string 17 | }{ 18 | {"1234.1234", "private-foobar", "58df8b0c36d6982b82c3ecf6b4662e34fe8c25bba48f5369f135bf843651c3a4"}, 19 | } 20 | 21 | for _, tt := range tests { 22 | sig := Sign([]byte(testSecret), tt.socketID, tt.channel) 23 | 24 | if got, want := sig, tt.signature; got != want { 25 | t.Errorf("Sign(%s, %s) => %q; want %q", tt.socketID, tt.channel, got, want) 26 | } 27 | } 28 | } 29 | 30 | func TestHandler(t *testing.T) { 31 | h := &Handler{Key: "278d425bdf160c739803", Secret: []byte(testSecret)} 32 | 33 | req, _ := http.NewRequest("POST", "?channel_name=private-foobar&socket_id=1234.1234", nil) 34 | resp := httptest.NewRecorder() 35 | 36 | h.ServeHTTP(resp, req) 37 | 38 | expected := `{"auth":"278d425bdf160c739803:58df8b0c36d6982b82c3ecf6b4662e34fe8c25bba48f5369f135bf843651c3a4"}` + "\n" 39 | 40 | if got, want := resp.Body.String(), expected; got != want { 41 | t.Fatalf("Body => %s; want %s", got, want) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /provider.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | 8 | "golang.org/x/net/context" 9 | ) 10 | 11 | var ( 12 | // ErrFailed can be used by providers to indicate that the deployment 13 | // failed. 14 | ErrFailed = errors.New("deployment failed") 15 | ) 16 | 17 | // Provider is something that's capable of fullfilling a deployment. 18 | type Provider interface { 19 | // Deploy should perform the deployment. An io.Writer can be provided 20 | // for providers to write log output to. If the deployment failed 21 | // without a specific error, and the user should view the logs to find 22 | // out why, then an ErrFailed should be returned. 23 | Deploy(context.Context, *Deployment, io.Writer) error 24 | 25 | // Name should return the name of this provider. 26 | Name() string 27 | } 28 | 29 | type ProviderFunc func(context.Context, *Deployment, io.Writer) error 30 | 31 | func (f ProviderFunc) Deploy(ctx context.Context, d *Deployment, w io.Writer) error { 32 | return f(ctx, d, w) 33 | } 34 | 35 | func (f ProviderFunc) Name() string { 36 | return fmt.Sprintf("func: %v", f) 37 | } 38 | 39 | var _ Provider = &NullProvider{} 40 | 41 | // NullProvider is a Provider that does nothing. 42 | type NullProvider struct{} 43 | 44 | func (p *NullProvider) Deploy(ctx context.Context, d *Deployment, w io.Writer) error { 45 | return nil 46 | } 47 | 48 | func (p *NullProvider) Name() string { 49 | return "null" 50 | } 51 | -------------------------------------------------------------------------------- /provider/empire/client.go: -------------------------------------------------------------------------------- 1 | package empire 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | 7 | "github.com/remind101/tugboat/pkg/heroku" 8 | ) 9 | 10 | type client struct { 11 | *heroku.Service 12 | } 13 | 14 | func newClient(c *http.Client) *client { 15 | if c == nil { 16 | c = http.DefaultClient 17 | } 18 | 19 | return &client{ 20 | Service: heroku.NewService(c), 21 | } 22 | } 23 | 24 | func (c *client) Deploy(image string, w io.Writer) error { 25 | d := struct { 26 | Image string `json:"image"` 27 | }{ 28 | Image: image, 29 | } 30 | 31 | return c.Post(w, "/deploys", &d) 32 | } 33 | -------------------------------------------------------------------------------- /provider/empire/empire.go: -------------------------------------------------------------------------------- 1 | package empire 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net" 7 | "net/http" 8 | "net/url" 9 | "os" 10 | "time" 11 | 12 | "github.com/remind101/tugboat" 13 | "github.com/remind101/tugboat/pkg/heroku" 14 | "golang.org/x/net/context" 15 | ) 16 | 17 | type Provider struct { 18 | client *client 19 | } 20 | 21 | func NewProvider(url, token string) *Provider { 22 | c := newClient(&http.Client{ 23 | Transport: newTransport(token), 24 | }) 25 | c.URL = url 26 | 27 | return &Provider{ 28 | client: c, 29 | } 30 | } 31 | 32 | func (p *Provider) Name() string { 33 | return "empire" 34 | } 35 | 36 | func (p *Provider) Deploy(ctx context.Context, d *tugboat.Deployment, w io.Writer) error { 37 | image := newImage(d) 38 | fmt.Fprintf(w, "Deploying %s to %s...\n", image, p.client.URL) 39 | 40 | if err := p.client.Deploy(newImage(d), w); err != nil { 41 | return err 42 | } 43 | 44 | return nil 45 | } 46 | 47 | func newTransport(token string) http.RoundTripper { 48 | proxy := &http.Transport{ 49 | Proxy: func(_ *http.Request) (*url.URL, error) { 50 | proxy := os.Getenv("EMPIRE_PROXY") 51 | if proxy == "" { 52 | return nil, nil 53 | } 54 | 55 | fmt.Println("Using proxy", proxy) 56 | 57 | return url.Parse(proxy) 58 | }, 59 | Dial: (&net.Dialer{ 60 | Timeout: 30 * time.Second, 61 | KeepAlive: 30 * time.Second, 62 | }).Dial, 63 | TLSHandshakeTimeout: 10 * time.Second, 64 | } 65 | 66 | return &heroku.Transport{ 67 | Password: token, 68 | Transport: proxy, 69 | } 70 | } 71 | 72 | // newImage returns the Docker image that should be used for the given 73 | // deployment. It assumes that the docker images are tagged with the full git 74 | // Sha and that the Docker repository matches the github repository. 75 | func newImage(d *tugboat.Deployment) string { 76 | return fmt.Sprintf("%s:%s", d.Repo, d.Sha) 77 | } 78 | -------------------------------------------------------------------------------- /provider/fake/fake.go: -------------------------------------------------------------------------------- 1 | package fake 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | 8 | "github.com/remind101/tugboat" 9 | "golang.org/x/net/context" 10 | ) 11 | 12 | var ( 13 | _ tugboat.Provider = &Provider{} 14 | 15 | // DefaultScenarios are the default set of scenarios that will be played 16 | // back. 17 | DefaultScenarios = map[string]Scenario{ 18 | "Ok": Scenario{ 19 | Logs: `-----> Fetching custom git buildpack... done 20 | -----> Go app detected 21 | -----> Using go1.3 22 | -----> Running: godep go install -tags heroku ./... 23 | -----> Discovering process types 24 | Procfile declares types -> web 25 | 26 | -----> Compressing... done, 1.6MB 27 | -----> Launching... done, v6 28 | https://acme-inc.herokuapp.com/ deployed to Heroku 29 | `, 30 | }, 31 | "Failure": Scenario{ 32 | Error: errors.New("boom"), 33 | }, 34 | } 35 | ) 36 | 37 | // Provider is a fake provider. 38 | type Provider struct { 39 | Scenarios map[string]Scenario 40 | } 41 | 42 | func NewProvider() *Provider { 43 | return &Provider{ 44 | Scenarios: DefaultScenarios, 45 | } 46 | } 47 | 48 | func (p *Provider) Deploy(ctx context.Context, d *tugboat.Deployment, w io.Writer) error { 49 | s, ok := p.Scenarios[d.Description] 50 | if !ok { 51 | return fmt.Errorf("no scenario for %s", d.Repo) 52 | } 53 | 54 | if _, err := io.WriteString(w, s.Logs); err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | } 60 | 61 | func (p *Provider) Name() string { 62 | return "fake" 63 | } 64 | 65 | type Scenario struct { 66 | Logs string 67 | Error error 68 | } 69 | -------------------------------------------------------------------------------- /provider_test.go: -------------------------------------------------------------------------------- 1 | package tugboat_test 2 | 3 | import ( 4 | "io" 5 | "log" 6 | 7 | "github.com/remind101/tugboat" 8 | "golang.org/x/net/context" 9 | ) 10 | 11 | func deploy(ctx context.Context, d *tugboat.Deployment, w io.Writer) error { 12 | // Write some log lines 13 | io.WriteString(w, `My 14 | Log 15 | Lines`) 16 | 17 | // Successful deployment! 18 | return nil 19 | } 20 | 21 | func Example() { 22 | // First, you'll want to create a tugboat.Client and point it at a 23 | // tugboat server. 24 | c := tugboat.NewClient(nil) 25 | 26 | // Options should be parsed from the github webhook. 27 | opts := tugboat.DeployOpts{ 28 | ID: 1, 29 | Sha: "827fecd2d36ebeaa2fd05aa8ef3eed1e56a8cd57", 30 | Ref: "master", 31 | Environment: "staging", 32 | Description: "Deploying to staging", 33 | Repo: "remind101/acme-inc", 34 | } 35 | 36 | // Calling Deploy will perform the deployment and record the 37 | // logs. 38 | if _, err := c.Deploy(context.TODO(), opts, tugboat.ProviderFunc(deploy)); err != nil { 39 | log.Fatal(err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pusher.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "errors" 5 | "net/url" 6 | "strings" 7 | ) 8 | 9 | // Pusher represents a pusher client that can publish events to a channel. 10 | type Pusher interface { 11 | Publish(data, event string, channels ...string) error 12 | } 13 | 14 | // nullPusher is a pusher client that does nothing. 15 | type nullPusher struct{} 16 | 17 | func (p *nullPusher) Publish(data, event string, channels ...string) error { 18 | return nil 19 | } 20 | 21 | type event struct { 22 | data string 23 | event string 24 | channels []string 25 | } 26 | 27 | // asyncPusher is a pusher client that sends pusher events in a go routine. 28 | type asyncPusher struct { 29 | pusher Pusher 30 | events chan *event 31 | } 32 | 33 | func newAsyncPusher(pusher Pusher, enqueue int) *asyncPusher { 34 | p := &asyncPusher{ 35 | pusher: pusher, 36 | events: make(chan *event, enqueue), 37 | } 38 | go p.start() 39 | return p 40 | } 41 | 42 | func (p *asyncPusher) Publish(data, evt string, channels ...string) error { 43 | p.events <- &event{ 44 | data: data, 45 | event: evt, 46 | channels: channels, 47 | } 48 | return nil 49 | } 50 | 51 | func (p *asyncPusher) start() { 52 | for event := range p.events { 53 | p.pusher.Publish(event.data, event.event, event.channels...) 54 | } 55 | } 56 | 57 | type PusherCredentials struct { 58 | AppID string 59 | Key string 60 | Secret string 61 | } 62 | 63 | func ParsePusherCredentials(uri string) (*PusherCredentials, error) { 64 | u, err := url.Parse(uri) 65 | if err != nil { 66 | return nil, err 67 | } 68 | 69 | if u.User == nil { 70 | return nil, errors.New("no credentials provided for pusher") 71 | } 72 | 73 | key := u.User.Username() 74 | secret, ok := u.User.Password() 75 | if !ok { 76 | return nil, errors.New("no password provided") 77 | } 78 | 79 | appID := strings.Replace(u.Path, "/apps/", "", 1) 80 | 81 | return &PusherCredentials{ 82 | AppID: appID, 83 | Key: key, 84 | Secret: secret, 85 | }, nil 86 | } 87 | -------------------------------------------------------------------------------- /pusher_test.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | ) 7 | 8 | type fakePusher struct { 9 | events chan string 10 | } 11 | 12 | func (p *fakePusher) Publish(data, event string, channels ...string) error { 13 | p.events <- event 14 | return nil 15 | } 16 | 17 | func TestAsyncPusher(t *testing.T) { 18 | f := &fakePusher{events: make(chan string, 1)} 19 | p := newAsyncPusher(f, 1) 20 | 21 | if err := p.Publish("data", "event", "channel"); err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | select { 26 | case e := <-f.events: 27 | if got, want := e, "event"; got != want { 28 | t.Fatalf("Event => %s; want %s", got, want) 29 | } 30 | case <-time.After(1 * time.Second): 31 | t.Fatal("timeout") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /server/api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gorilla/mux" 7 | "github.com/remind101/tugboat" 8 | ) 9 | 10 | const AcceptHeader = "application/vnd.tugboat+json; version=1" 11 | 12 | type Config struct { 13 | Auth func(http.Handler) http.Handler 14 | Secret string 15 | } 16 | 17 | func New(t *tugboat.Tugboat, config Config) http.Handler { 18 | r := mux.NewRouter() 19 | 20 | auth := config.Auth 21 | 22 | r.Handle("/jobs", auth(&GetDeploymentsHandler{t})).Methods("GET") 23 | r.Handle("/jobs/{id}", auth(&GetDeploymentHandler{t})).Methods("GET") 24 | r.Handle("/deployments", authProvider(t, &PostDeploymentsHandler{t})).Methods("POST") 25 | r.Handle("/deployments/{id}/logs", authProvider(t, &PostLogsHandler{t})).Methods("POST") 26 | r.Handle("/deployments/{id}/status", authProvider(t, &PostStatusHandler{t})).Methods("POST") 27 | 28 | return r 29 | } 30 | -------------------------------------------------------------------------------- /server/github/github.go: -------------------------------------------------------------------------------- 1 | package github 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | 8 | "github.com/ejholmes/hookshot" 9 | "github.com/remind101/tugboat" 10 | "golang.org/x/net/context" 11 | ) 12 | 13 | func New(tug *tugboat.Tugboat, secret string) http.Handler { 14 | r := hookshot.NewRouter() 15 | 16 | r.Handle("ping", http.HandlerFunc(Ping)) 17 | r.Handle("deployment", hookshot.Authorize(&DeploymentHandler{tugboat: tug}, secret)) 18 | 19 | return r 20 | } 21 | 22 | func Ping(w http.ResponseWriter, r *http.Request) { 23 | io.WriteString(w, "Ok\n") 24 | } 25 | 26 | type DeploymentHandler struct { 27 | tugboat *tugboat.Tugboat 28 | } 29 | 30 | func (h *DeploymentHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 31 | opts, err := tugboat.NewDeployOptsFromReader(r.Body) 32 | if err != nil { 33 | http.Error(w, err.Error(), http.StatusBadRequest) 34 | return 35 | } 36 | 37 | ds, err := h.tugboat.Deploy(context.TODO(), opts) 38 | if err != nil { 39 | http.Error(w, err.Error(), http.StatusBadRequest) 40 | return 41 | } 42 | 43 | for _, d := range ds { 44 | fmt.Fprintf(w, "Deployment: %s\n", d.ID) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /store.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | type store struct { 4 | db *db 5 | } 6 | 7 | func (s *store) Reset() error { 8 | _, err := s.db.Exec(`TRUNCATE TABLE deployments CASCADE`) 9 | return err 10 | } 11 | -------------------------------------------------------------------------------- /tugboat_test.go: -------------------------------------------------------------------------------- 1 | package tugboat 2 | 3 | import ( 4 | "errors" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestUpdateStatus(t *testing.T) { 10 | boom := "boom" 11 | 12 | tests := []struct { 13 | fn func() error 14 | status StatusUpdate 15 | }{ 16 | { 17 | fn: func() error { 18 | return nil 19 | }, 20 | status: StatusUpdate{ 21 | Status: StatusSucceeded, 22 | }, 23 | }, 24 | { 25 | fn: func() error { 26 | return ErrFailed 27 | }, 28 | status: StatusUpdate{ 29 | Status: StatusFailed, 30 | }, 31 | }, 32 | { 33 | fn: func() error { 34 | return errors.New(boom) 35 | }, 36 | status: StatusUpdate{ 37 | Status: StatusErrored, 38 | Error: &boom, 39 | }, 40 | }, 41 | { 42 | fn: func() error { 43 | panic("boom") 44 | }, 45 | status: StatusUpdate{ 46 | Status: StatusErrored, 47 | Error: &boom, 48 | }, 49 | }, 50 | { 51 | fn: func() error { 52 | panic(errors.New("boom")) 53 | }, 54 | status: StatusUpdate{ 55 | Status: StatusErrored, 56 | Error: &boom, 57 | }, 58 | }, 59 | } 60 | 61 | for i, tt := range tests { 62 | update := statusUpdate(tt.fn) 63 | 64 | if got, want := update, tt.status; !reflect.DeepEqual(got, want) { 65 | t.Fatalf("#%d: Status => %s; want %s", i, got, want) 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tugboattest/test.go: -------------------------------------------------------------------------------- 1 | package tugboattest 2 | 3 | import ( 4 | "net/http" 5 | "os" 6 | "testing" 7 | 8 | "github.com/ejholmes/flock" 9 | "github.com/remind101/tugboat" 10 | "github.com/remind101/tugboat/provider/fake" 11 | "github.com/remind101/tugboat/server" 12 | ) 13 | 14 | const GitHubSecret = "abcd" 15 | 16 | func New(t testing.TB) *tugboat.Tugboat { 17 | config := tugboat.Config{} 18 | config.DB = "postgres://localhost/tugboat?sslmode=disable" 19 | 20 | tug, err := tugboat.New(config) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | tug.Providers = []tugboat.Provider{fake.NewProvider()} 25 | 26 | if err := tug.Reset(); err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | return tug 31 | } 32 | 33 | func NewServer(tug *tugboat.Tugboat) http.Handler { 34 | config := server.Config{} 35 | config.GitHub.Secret = GitHubSecret 36 | return server.New(tug, config) 37 | } 38 | 39 | var dblock = "/tmp/tugboat.lock" 40 | 41 | // Run runs testing.M after aquiring a lock against the database. 42 | func Run(m *testing.M) { 43 | l, err := flock.NewPath(dblock) 44 | if err != nil { 45 | panic(err) 46 | } 47 | 48 | l.Lock() 49 | defer l.Unlock() 50 | 51 | os.Exit(m.Run()) 52 | } 53 | --------------------------------------------------------------------------------