├── .yardopts ├── .rspec ├── Gemfile ├── .gitignore ├── lib ├── platform-api │ └── version.rb └── platform-api.rb ├── CONTRIBUTORS.md ├── spec ├── spec_helper.rb └── acceptance │ └── generated_client_spec.rb ├── config └── client-config.rb ├── Rakefile ├── CONTRIBUTING.md ├── platform-api.gemspec ├── LICENSE.md ├── Gemfile.lock └── README.md /.yardopts: -------------------------------------------------------------------------------- 1 | -m markdown 2 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require spec_helper 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .yardoc 2 | doc/ 3 | pkg/ 4 | spec/examples.txt 5 | -------------------------------------------------------------------------------- /lib/platform-api/version.rb: -------------------------------------------------------------------------------- 1 | module PlatformAPI 2 | VERSION = '2.1.0' 3 | end 4 | -------------------------------------------------------------------------------- /lib/platform-api.rb: -------------------------------------------------------------------------------- 1 | require 'heroics' 2 | require 'moneta' 3 | 4 | require_relative '../config/client-config' 5 | # Ruby HTTP client for the Heroku API. 6 | module PlatformAPI 7 | end 8 | 9 | require 'platform-api/client' 10 | require 'platform-api/version' 11 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | * Albert Peng 2 | * Brandur 3 | * David Fernandez 4 | * Jamu Kakar 5 | * Mark Pundsack 6 | * Matt Gauger 7 | * Owen Jacobson 8 | * Paul Sadauskas 9 | * Wesley Beary 10 | * geemus -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'pry' 2 | RSpec.configure do |config| 3 | config.expect_with :rspec do |expectations| 4 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 5 | end 6 | 7 | config.mock_with :rspec do |mocks| 8 | mocks.verify_partial_doubles = true 9 | end 10 | 11 | config.shared_context_metadata_behavior = :apply_to_host_groups 12 | config.filter_run_when_matching :focus 13 | config.example_status_persistence_file_path = "spec/examples.txt" 14 | config.warnings = true 15 | if config.files_to_run.one? 16 | config.default_formatter = 'doc' 17 | end 18 | config.order = :random 19 | Kernel.srand config.seed 20 | end 21 | -------------------------------------------------------------------------------- /config/client-config.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | require 'heroics' 3 | require File.join(File.expand_path('../..', __FILE__), 'lib', 'platform-api', 'version.rb') 4 | 5 | Heroics.default_configuration do |config| 6 | config.base_url = 'https://api.heroku.com' 7 | config.module_name = 'PlatformAPI' 8 | config.schema_filepath = File.join(File.expand_path('../..', __FILE__), 'schema.json') 9 | 10 | config.headers = { 11 | 'Accept' => 'application/vnd.heroku+json; version=3', 12 | 'User-Agent' => "platform-api/#{PlatformAPI::VERSION}" 13 | } 14 | config.ruby_name_replacement_patterns = { 15 | /add[^a-z]+on/i => 'addon', 16 | /[\s-]+/ => '_', 17 | } 18 | # This needs to be in single quotes to avoid interpolation during the client 19 | # build 20 | config.cache_path = '#{Dir.home}/.heroics/platform-api' 21 | end 22 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'yard' 3 | 4 | desc 'Generate API documentation' 5 | YARD::Rake::YardocTask.new 6 | 7 | desc 'Download the latest schema and build a new client' 8 | task :build do 9 | sh 'curl -o schema.json -H "Accept: application/vnd.heroku+json; version=3" https://api.heroku.com/schema' 10 | sh 'bundle exec heroics-generate ./config/client-config.rb > lib/platform-api/client.rb' 11 | end 12 | 13 | desc 'Publish API documentation' 14 | task :publish do 15 | sh 'rake yard' 16 | sh 'cp -R doc /tmp/platform-api-doc' 17 | sh 'git checkout gh-pages' 18 | sh 'cp -R /tmp/platform-api-doc/* .' 19 | sh 'rm -rf /tmp/platform-api-doc' 20 | sh 'git add .' 21 | sh 'git commit -am "Rebuild documentation"' 22 | sh 'git push origin gh-pages' 23 | sh 'git checkout master' 24 | end 25 | 26 | begin 27 | require "rspec/core/rake_task" 28 | RSpec::Core::RakeTask.new(:spec) 29 | task default: [:spec] 30 | rescue LoadError 31 | end 32 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Getting Involved 2 | 3 | New contributors are always welcome, when it doubt please ask questions. We strive to be an open and welcoming community. Please be nice to one another. 4 | 5 | ### Coding 6 | 7 | * Pick a task: 8 | * Offer feedback on open [pull requests](https://github.com/heroku/platform/pulls). 9 | * Review open [issues](https://github.com/heroku/platform/issues) for things to help on. 10 | * [Create an issue](https://github.com/heroku/platform/issues/new) to start a discussion on additions or features. 11 | * Fork the project, add your changes and tests to cover them in a topic branch. 12 | * Commit your changes and rebase against `heroku/platform` to ensure everything is up to date. 13 | * [Submit a pull request](https://github.com/heroku/platform/compare/). 14 | * This project follows [semver](http://semver.org) from version 1.0.0. Please 15 | be sure to keep this in mind if you're the project maintainer. 16 | 17 | ### Non-Coding 18 | 19 | * Offer feedback on open [issues](https://github.com/heroku/platform/issues). 20 | * Organize or volunteer at events. 21 | -------------------------------------------------------------------------------- /platform-api.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | lib = File.expand_path('../lib', __FILE__) 4 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 5 | 6 | require 'platform-api/version' 7 | 8 | Gem::Specification.new do |spec| 9 | spec.name = 'platform-api' 10 | spec.version = PlatformAPI::VERSION 11 | spec.authors = ['jkakar'] 12 | spec.email = ['jkakar@kakar.ca'] 13 | spec.description = 'Ruby HTTP client for the Heroku API.' 14 | spec.summary = 'Ruby HTTP client for the Heroku API.' 15 | spec.homepage = 'https://github.com/heroku/platform-api' 16 | spec.license = 'MIT' 17 | 18 | spec.files = `git ls-files`.split($/) 19 | spec.test_files = spec.files.grep('^(test|spec|features)/') 20 | spec.require_paths = ['lib'] 21 | 22 | spec.add_development_dependency 'bundler', '~> 1.3' 23 | spec.add_development_dependency 'rake' 24 | spec.add_development_dependency 'yard' 25 | spec.add_development_dependency 'pry' 26 | spec.add_development_dependency 'netrc' 27 | spec.add_development_dependency 'rspec' 28 | 29 | spec.add_dependency 'heroics', '~> 0.0.23' 30 | spec.add_dependency 'moneta', '~> 0.8.1' 31 | end 32 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2016 [CONTRIBUTORS.md](https://github.com/heroku/platform/blob/master/CONTRIBUTORS.md) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | platform-api (2.1.0) 5 | heroics (~> 0.0.23) 6 | moneta (~> 0.8.1) 7 | 8 | GEM 9 | remote: https://rubygems.org/ 10 | specs: 11 | coderay (1.1.1) 12 | diff-lcs (1.3) 13 | erubis (2.7.0) 14 | excon (0.57.0) 15 | heroics (0.0.23) 16 | erubis (~> 2.0) 17 | excon 18 | multi_json (>= 1.9.2) 19 | method_source (0.8.2) 20 | moneta (0.8.1) 21 | multi_json (1.12.1) 22 | netrc (0.11.0) 23 | pry (0.10.4) 24 | coderay (~> 1.1.0) 25 | method_source (~> 0.8.1) 26 | slop (~> 3.4) 27 | rake (10.5.0) 28 | rspec (3.5.0) 29 | rspec-core (~> 3.5.0) 30 | rspec-expectations (~> 3.5.0) 31 | rspec-mocks (~> 3.5.0) 32 | rspec-core (3.5.4) 33 | rspec-support (~> 3.5.0) 34 | rspec-expectations (3.5.0) 35 | diff-lcs (>= 1.2.0, < 2.0) 36 | rspec-support (~> 3.5.0) 37 | rspec-mocks (3.5.0) 38 | diff-lcs (>= 1.2.0, < 2.0) 39 | rspec-support (~> 3.5.0) 40 | rspec-support (3.5.0) 41 | slop (3.6.0) 42 | yard (0.8.7.6) 43 | 44 | PLATFORMS 45 | ruby 46 | 47 | DEPENDENCIES 48 | bundler (~> 1.3) 49 | netrc 50 | platform-api! 51 | pry 52 | rake 53 | rspec 54 | yard 55 | 56 | BUNDLED WITH 57 | 1.14.6 58 | -------------------------------------------------------------------------------- /spec/acceptance/generated_client_spec.rb: -------------------------------------------------------------------------------- 1 | require 'netrc' 2 | require 'platform-api' 3 | 4 | describe 'The generated platform api client' do 5 | it "can get account info" do 6 | expect(client.account.info(email)).not_to be_empty 7 | end 8 | 9 | it "can get addon info for an app" do 10 | expect(client.addon.list_by_app(an_app['name'])).not_to be_empty 11 | end 12 | 13 | it "can list apps" do 14 | expect(client.app.list).not_to be_empty 15 | end 16 | 17 | it "can get app info" do 18 | expect(client.app.info(an_app['name'])).to eq an_app 19 | end 20 | 21 | it "can get build info" do 22 | expect(client.build.list(an_app['name'])).not_to be_empty 23 | end 24 | 25 | it "can get config vars" do 26 | expect(client.config_var.info_for_app(an_app['name'])).not_to be_empty 27 | end 28 | 29 | it "can get domain list and info" do 30 | domains = client.domain.list(an_app['name']) 31 | expect(domains).not_to be_empty 32 | 33 | expect(client.domain.info(an_app['name'], domains.first['hostname'])).not_to be_empty 34 | end 35 | 36 | it "can get dyno sizes" do 37 | expect(client.dyno_size.list).not_to be_empty 38 | end 39 | 40 | it "can get add-on plan info" do 41 | expect(client.plan.list('heroku-postgresql')).not_to be_empty 42 | end 43 | 44 | it "can get release info" do 45 | expect(client.release.list(an_app['name'])).not_to be_empty 46 | end 47 | 48 | def an_app 49 | @app ||= client.app.list.first 50 | end 51 | 52 | def email 53 | @email 54 | end 55 | 56 | def client 57 | @client ||= 58 | begin 59 | entry = Netrc.read['api.heroku.com'] 60 | if entry 61 | oauth_token = entry.password 62 | @email = entry.login 63 | else 64 | oauth_token = ENV['OAUTH_TOKEN'] 65 | @email = ENV['ACCOUNT_EMAIL'] 66 | end 67 | PlatformAPI.connect_oauth(oauth_token) 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Platform API 2 | 3 | Ruby HTTP client for the Heroku API. 4 | 5 | > NOTE: v2.0.0 fixed a long-standing issue with duplicated link titles, which may break things if you were relying on the now-renamed methods. 6 | 7 | ## Installation 8 | 9 | Add this line to your application's Gemfile: 10 | 11 | ``` 12 | gem 'platform-api' 13 | ``` 14 | 15 | And then execute: 16 | 17 | ``` 18 | bundle 19 | ``` 20 | 21 | Or install it yourself as: 22 | 23 | ``` 24 | gem install platform-api 25 | ``` 26 | 27 | ## API documentation 28 | 29 | Jump right to the [API documentation](http://heroku.github.io/platform-api/_index.html) 30 | for the nitty gritty details. 31 | 32 | ## Usage guide 33 | 34 | The best place to start using the Heroku API is the [Platform API Reference](https://devcenter.heroku.com/articles/platform-api-reference). 35 | It has detailed descriptions of the HTTP API, including general information 36 | about authentication, caching, object identifiers, rate limits, etc. It also 37 | includes detailed information about each supported resource and the actions 38 | available for them. 39 | 40 | The table of contents lists all the resources that are supported, such as App, 41 | Add-on, Config Vars, Formation, etc. Each resource includes detailed 42 | information about the support actions. For example, the [Formation](https://devcenter.heroku.com/articles/platform-api-reference#formation) 43 | resource has [Info](https://devcenter.heroku.com/articles/platform-api-reference#formation-info), [List](https://devcenter.heroku.com/articles/platform-api-reference#formation-list), [Batch update](https://devcenter.heroku.com/articles/platform-api-reference#formation-batch-update), and [Update](https://devcenter.heroku.com/articles/platform-api-reference#formation-update) actions. 44 | 45 | Resources and their related actions are available as methods on the client. 46 | When the URL for an action includes parameters they're passed as arguments to 47 | the method. When the request expects a request payload it's passed as a Hash 48 | in the final argument to the method. 49 | 50 | For example, to get information about the `web` formation on the `sushi` app 51 | you'd invoke `heroku.formation.info('sushi', 'web')` and it would return a 52 | Ruby object that matches the one given in the [response example](https://devcenter.heroku.com/articles/platform-api-reference#formation-info). 53 | 54 | The [API documentation](http://heroku.github.io/platform-api/_index.html) contains a 55 | description of all available resources and methods. 56 | 57 | ### Handling errors 58 | 59 | The client uses [Excon](https://github.com/geemus/excon) under the hood and 60 | raises `Excon::Errors::Error` exceptions when errors occur. You can catch specific 61 | [Excon error types](https://github.com/geemus/excon/blob/master/lib/excon/errors.rb) if you want. 62 | 63 | ### A real world example 64 | 65 | Let's go through an example of creating an app and using the API to work with 66 | it. The first thing you need is a client setup with an OAuth token. You can 67 | create an OAuth token using the `heroku-oauth` toolbelt plugin: 68 | 69 | ```bash 70 | $ heroku plugins:install heroku-cli-oauth 71 | $ heroku authorizations:create -d "Platform API example token" 72 | Created OAuth authorization. 73 | ID: 2f01aac0-e9d3-4773-af4e-3e510aa006ca 74 | Description: Platform API example token 75 | Scope: global 76 | Token: e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2 77 | ``` 78 | 79 | Use the `Token` value when instantiating a client: 80 | 81 | ```ruby 82 | require 'platform-api' 83 | heroku = PlatformAPI.connect_oauth('e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2') 84 | ``` 85 | 86 | The [OAuth article](https://devcenter.heroku.com/articles/oauth) has more information about OAuth tokens, including how to 87 | create tokens with specific scopes. 88 | 89 | Now let's create an app: 90 | 91 | ```ruby 92 | heroku.app.create({}) 93 | => {"id"=>22979756, 94 | "name"=>"floating-retreat-4255", 95 | "dynos"=>0, 96 | "workers"=>0, 97 | "repo_size"=>nil, 98 | "slug_size"=>nil, 99 | "stack"=>"cedar", 100 | "requested_stack"=>nil, 101 | "create_status"=>"complete", 102 | "repo_migrate_status"=>"complete", 103 | "owner_delinquent"=>false, 104 | "owner_email"=>"jkakar@heroku.com", 105 | "owner_name"=>nil, 106 | "domain_name"=> 107 | {"id"=>nil, 108 | "app_id"=>22979756, 109 | "domain"=>"floating-retreat-4255.herokuapp.com", 110 | "base_domain"=>"herokuapp.com", 111 | "created_at"=>nil, 112 | "default"=>true, 113 | "updated_at"=>nil}, 114 | "web_url"=>"http://floating-retreat-4255.herokuapp.com/", 115 | "git_url"=>"git@heroku.com:floating-retreat-4255.git", 116 | "buildpack_provided_description"=>nil, 117 | "region"=>"us", 118 | "created_at"=>"2014/03/12 16:44:09 -0700", 119 | "archived_at"=>nil, 120 | "released_at"=>"2014/03/12 16:44:10 -0700", 121 | "updated_at"=>"2014/03/12 16:44:10 -0700"} 122 | ``` 123 | 124 | We can read the same information back with the `info` method. 125 | 126 | ```ruby 127 | heroku.app.info('floating-retreat-4255') 128 | => {"id"=>22979756, 129 | "name"=>"floating-retreat-4255", 130 | "dynos"=>0, 131 | "workers"=>0, 132 | "repo_size"=>nil, 133 | "slug_size"=>nil, 134 | "stack"=>"cedar", 135 | "requested_stack"=>nil, 136 | "create_status"=>"complete", 137 | "repo_migrate_status"=>"complete", 138 | "owner_delinquent"=>false, 139 | "owner_email"=>"jkakar@heroku.com", 140 | "owner_name"=>nil, 141 | "domain_name"=> 142 | {"id"=>nil, 143 | "app_id"=>22979756, 144 | "domain"=>"floating-retreat-4255.herokuapp.com", 145 | "base_domain"=>"herokuapp.com", 146 | "created_at"=>nil, 147 | "default"=>true, 148 | "updated_at"=>nil}, 149 | "web_url"=>"http://floating-retreat-4255.herokuapp.com/", 150 | "git_url"=>"git@heroku.com:floating-retreat-4255.git", 151 | "buildpack_provided_description"=>nil, 152 | "region"=>"us", 153 | "created_at"=>"2014/03/12 16:44:09 -0700", 154 | "archived_at"=>nil, 155 | "released_at"=>"2014/03/12 16:44:12 -0700", 156 | "updated_at"=>"2014/03/12 16:44:12 -0700"} 157 | ``` 158 | 159 | Let's add a Heroku PostgreSQL database to our app now: 160 | 161 | ```ruby 162 | heroku.addon.create('floating-retreat-4255', {'plan' => 'heroku-postgresql:dev'}) 163 | => {"config_vars"=>["HEROKU_POSTGRESQL_COBALT_URL"], 164 | "created_at"=>"2014-03-13T00:28:55Z", 165 | "id"=>"79a0c826-06be-4dcd-8bb5-f2c1b1bc2beb", 166 | "name"=>"heroku-postgresql-cobalt", 167 | "plan"=> 168 | {"id"=>"95a1ce4c-c651-45dc-aaee-79b4603e76b7", 169 | "name"=>"heroku-postgresql:dev"}, 170 | "provider_id"=>"resource5924903@heroku.com", 171 | "updated_at"=>"2014-03-13T00:28:55Z"} 172 | ``` 173 | 174 | Excellent! That will have added a config var which we can now see: 175 | 176 | ```ruby 177 | heroku.config_var.info_for_app('floating-retreat-4255') 178 | => {"HEROKU_POSTGRESQL_COBALT_URL"=>"postgres://"} 179 | ``` 180 | 181 | And there we go, we have the config var. Let's set an additional config var, 182 | which will also demonstrate how to make a request that needs a payload: 183 | 184 | ```ruby 185 | heroku.config_var.update('floating-retreat-4255', {'MYAPP' => 'ROCKS'}) 186 | => {"HEROKU_POSTGRESQL_COBALT_URL"=>"postgres://", 187 | "MYAPP"=>"ROCKS"} 188 | ``` 189 | 190 | As you can see, any action that needs a request body takes it as a plain Ruby 191 | object, as the final parameter of the method call. 192 | 193 | Let's continue by deploying a sample app. We'll use the 194 | [Geosockets](https://github.com/heroku-examples/geosockets) example app: 195 | 196 | ```bash 197 | $ git clone https://github.com/heroku-examples/geosockets.git 198 | Cloning into 'geosockets'... 199 | remote: Reusing existing pack: 489, done. 200 | remote: Total 489 (delta 0), reused 0 (delta 0) 201 | Receiving objects: 100% (489/489), 1.95 MiB | 1.14 MiB/s, done. 202 | Resolving deltas: 100% (244/244), done. 203 | Checking connectivity... done. 204 | $ cd geosockets 205 | $ git remote add heroku git@heroku.com:floating-retreat-4255.git 206 | $ heroku labs:enable websockets 207 | $ heroku addons:add openredis:micro # $10/month 208 | Adding openredis:micro on floating-retreat-4255... done, v10 ($10/mo) 209 | Use `heroku addons:docs openredis` to view documentation. 210 | $ git push heroku master 211 | Initializing repository, done. 212 | Counting objects: 489, done. 213 | Delta compression using up to 4 threads. 214 | Compressing objects: 100% (229/229), done. 215 | Writing objects: 100% (489/489), 1.95 MiB | 243.00 KiB/s, done. 216 | Total 489 (delta 244), reused 489 (delta 244) 217 | 8< snip 8< 218 | ``` 219 | 220 | We can now use the API to see our `web` process running: 221 | 222 | ```ruby 223 | heroku.formation.list('floating-retreat-4255') 224 | => [{"command"=>"coffee index.coffee", 225 | "created_at"=>"2014-03-13T04:13:37Z", 226 | "id"=>"f682b260-8089-4e18-b792-688cc02bf923", 227 | "type"=>"web", 228 | "quantity"=>1, 229 | "size"=>"1X", 230 | "updated_at"=>"2014-03-13T04:13:37Z"}] 231 | ``` 232 | 233 | Let's change `web` process to run on a 2X dyno: 234 | 235 | ```ruby 236 | heroku.formation.batch_update('floating-retreat-4255', 237 | {"updates" => [{"process" => "web", 238 | "quantity" => 1, 239 | "size" => "2X"}]}) 240 | => [{"command"=>"coffee index.coffee", 241 | "created_at"=>"2014-03-13T04:13:37Z", 242 | "id"=>"f682b260-8089-4e18-b792-688cc02bf923", 243 | "type"=>"web", 244 | "quantity"=>1, 245 | "size"=>"2X", 246 | "updated_at"=>"2014-03-13T04:22:15Z"}] 247 | ``` 248 | 249 | We could have included a number of different kinds of processes in the last 250 | command. We can use the singular update action to modify a single formation 251 | type: 252 | 253 | ```ruby 254 | heroku.formation.update('floating-retreat-4255', 'web', {"size" => "1X"}) 255 | => {"command"=>"coffee index.coffee", 256 | "created_at"=>"2014-03-13T04:13:37Z", 257 | "id"=>"f682b260-8089-4e18-b792-688cc02bf923", 258 | "type"=>"web", 259 | "quantity"=>1, 260 | "size"=>"1X", 261 | "updated_at"=>"2014-03-13T04:24:46Z"} 262 | ``` 263 | 264 | Hopefully this has given you a taste of how the client works. If you have 265 | questions please feel free to file issues. 266 | 267 | ### Debugging 268 | 269 | Sometimes it helps to see more information about the requests flying by. You 270 | can start your program or an `irb` session with the `EXCON_DEBUG=1` 271 | environment variable to cause request and response data to be written to 272 | `STDERR`. 273 | 274 | ### Passing custom headers 275 | 276 | The various `connect` methods take an options hash that you can use to include 277 | custom headers to include with every request: 278 | 279 | ```ruby 280 | client = PlatformAPI.connect('my-api-key', default_headers: {'Foo' => 'Bar'}) 281 | ``` 282 | 283 | ### Using a custom cache 284 | 285 | By default, the `platform-api` will cache data in `~/.heroics/platform-api`. 286 | Use a different caching by passing in the [Moneta](https://github.com/minad/moneta) 287 | instance you want to use: 288 | 289 | ```ruby 290 | client = PlatformAPI.connect('my-api-key', cache: Moneta.new(:Memory)) 291 | ``` 292 | 293 | ### Connecting to a different host 294 | 295 | Connect to a different host by passing a `url` option: 296 | 297 | ```ruby 298 | client = PlatformAPI.connect('my-api-key', url: 'https://api.example.com') 299 | ``` 300 | 301 | ## Building and releasing 302 | 303 | ### Generate a new client 304 | 305 | Generate a new client from the Heroku Platform API JSON schema: 306 | 307 | ``` 308 | rake build 309 | ``` 310 | 311 | Remember to commit and push the changes to Github. 312 | 313 | ### Release a new gem 314 | 315 | * This project follows [semver](http://semver.org) from version 1.0.0. Please 316 | be sure to keep this in mind if you're the project maintainer. 317 | * Be sure to run the very basic acceptance rspecs. The rspecs will attempt 318 | to parse your oauth token for `api.heroku.com` from your `.netrc`. You can 319 | optionally use the `OAUTH_TOKEN` and `ACCOUNT_EMAIL` environment variables. 320 | They don't mutate anything but they might in the future. 321 | * Bump the version in `lib/platform-api/version.rb` 322 | * `bundle install` to update Gemfile.lock 323 | * `git commit -m 'vX.Y.Z' to stage the version and Gemfile.lock changes 324 | * `rake release` to push git changes and to release to Rubygems 325 | 326 | ### Building API documentation 327 | 328 | Build documentation with: 329 | 330 | ``` 331 | rake yard 332 | ``` 333 | 334 | And then visit `doc/index.html` to read it. Alternately, build and publish 335 | it to Github Pages in one step with: 336 | 337 | ``` 338 | rake publish 339 | ``` 340 | 341 | You can see it live on [Github Pages](http://heroku.github.io/platform-api/). 342 | 343 | ## Contributing 344 | 345 | 1. [Fork the repository](https://github.com/heroku/platform-api/fork). 346 | 2. Create your feature branch: `git checkout -b my-new-feature` 347 | 3. Commit your changes: `git commit -am 'Add some feature'` 348 | 4. Push to the branch: `git push origin my-new-feature` 349 | 5. Create new pull request. 350 | --------------------------------------------------------------------------------