twelvedata_ruby 0.2.2 โ†’ 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,9 +1,18 @@
1
1
  # TwelvedataRuby
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/twelvedata_ruby.svg)](https://badge.fury.io/rb/twelvedata_ruby)
3
+ [![Gem Version](https://badge.fury.io/rb/ruby.svg?icon=si%3Arubygems)](https://badge.fury.io/rb/ruby)
4
4
 
5
- TwelvedataRuby is a Ruby library that exposes some convenient ways to access Twelve Data API to get information on stock, forex, crypto, and other financial market data. In order to do so, a free API key is required which can be easily requested [here](https://twelvedata.com/pricing). Visit their [API's full documentation](https://twelvedata.com/docs)
5
+ A Ruby client library for accessing [Twelve Data's](https://twelvedata.com) comprehensive financial API. Get real-time and historical data for stocks, forex, cryptocurrencies, ETFs, indices, and more.
6
6
 
7
+ ## Features
8
+
9
+ - ๐Ÿš€ **Modern Ruby** - Requires Ruby 3.4.0+, follows modern Ruby practices
10
+ - ๐Ÿ“ˆ **Comprehensive API Coverage** - All Twelve Data endpoints supported
11
+ - ๐Ÿ”’ **Type Safety** - Strong parameter validation and error handling
12
+ - ๐Ÿ“Š **Multiple Formats** - JSON and CSV response formats
13
+ - ๐Ÿงช **Well Tested** - 100% test coverage
14
+ - ๐Ÿ”ง **Developer Friendly** - Excellent error messages and debugging support
15
+ - โšก **High Performance** - Built on HTTPX for concurrent requests
7
16
 
8
17
  ## Installation
9
18
 
@@ -15,142 +24,437 @@ gem 'twelvedata_ruby'
15
24
 
16
25
  And then execute:
17
26
 
18
- $ bundle install
27
+ ```bash
28
+ bundle install
29
+ ```
19
30
 
20
31
  Or install it yourself as:
21
32
 
22
- $ gem install twelvedata_ruby
33
+ ```bash
34
+ gem install twelvedata_ruby
35
+ ```
23
36
 
24
- ## Usage
37
+ ## Quick Start
25
38
 
26
- The preferred way to include the Twelve Data API key in the request payload is to assign it to an ENVIRONMENT variable which your Ruby application can fetch if none was explicitly assigned. The default ENVIRONMENTt variable name is `TWELVEDATA_API_KEY` but you can configure this to any other value using the `#apikey_env_var_name=` setter method.
39
+ ### 1. Get Your API Key
27
40
 
28
- To get hold of the singleton `TwelvedataRuby::Client.instance`, you can directly used that inherited instance method from the mixed in `Singleton` module or thru the gem's module helper class method:
41
+ Sign up for a free API key at [Twelve Data](https://twelvedata.com/pricing).
42
+
43
+ ### 2. Basic Usage
29
44
 
30
45
  ```ruby
31
- require "twelvedata_ruby"
46
+ require 'twelvedata_ruby'
47
+
48
+ # Option 1: Configure with API key directly
49
+ client = TwelvedataRuby.client(apikey: "your-api-key-here")
50
+
51
+ # Option 2: Use environment variable (recommended)
52
+ ENV['TWELVEDATA_API_KEY'] = 'your-api-key-here'
32
53
  client = TwelvedataRuby.client
54
+
55
+ # Get a stock quote
56
+ response = client.quote(symbol: "AAPL")
57
+ puts response.parsed_body
58
+ # => {
59
+ # symbol: "AAPL",
60
+ # name: "Apple Inc",
61
+ # exchange: "NASDAQ",
62
+ # currency: "USD",
63
+ # datetime: "2024-01-15",
64
+ # open: "185.00",
65
+ # high: "187.50",
66
+ # low: "184.20",
67
+ # close: "186.75",
68
+ # volume: "45678900",
69
+ # ...
70
+ # }
33
71
  ```
34
72
 
35
- By not passing anything to the options method parameters, the `client` instance attributes will have default values. Though you can still set different values to the attributes through their helper setter methods:
73
+ ## API Reference
74
+
75
+ ### Stock Market Data
36
76
 
37
77
  ```ruby
38
- client.apikey = "twelvedata-apikey"
39
- client.apikey_env_var_name = "the_environment_variable_name" # the helper getter method will upcase the value
40
- client.connect_timeout = 300 # can also accept "300"
78
+ # Real-time quote
79
+ client.quote(symbol: "AAPL")
80
+ client.quote(symbol: "GOOGL", exchange: "NASDAQ")
81
+
82
+ # Current price only
83
+ client.price(symbol: "TSLA")
84
+
85
+ # Historical time series data
86
+ client.time_series(
87
+ symbol: "AAPL",
88
+ interval: "1day",
89
+ start_date: "2024-01-01",
90
+ end_date: "2024-01-31"
91
+ )
92
+
93
+ # End of day prices
94
+ client.eod(symbol: "MSFT")
95
+
96
+ # Search for symbols
97
+ client.symbol_search(symbol: "Apple")
41
98
  ```
42
99
 
43
- or simply set them all at once:
100
+ ### Forex & Currency
44
101
 
45
102
  ```ruby
46
- require "twelvedata_ruby"
47
- client = TwelvedataRuby.client(apikey: "twelvedata-apikey", connect_timeout: 300)
48
- # or client = TwelvedataRuby.client(apikey_env_var_name: "the_environment_variable_name", connect_timeout: 300)
103
+ # Exchange rates
104
+ client.exchange_rate(symbol: "USD/EUR")
105
+
106
+ # Currency conversion
107
+ client.currency_conversion(symbol: "USD/EUR", amount: 100)
108
+
109
+ # Available forex pairs
110
+ client.forex_pairs
49
111
  ```
50
112
 
51
- The default values though are sufficient already.
113
+ ### Cryptocurrency
52
114
 
53
- Getting any type of financial data then from the API, simply invoke any valid endpoint name to the client instance. For example, to fetch some data for `GOOG` stock symbol using quote, timeseries, price, and etd API endpoints:
115
+ ```ruby
116
+ # Crypto quotes
117
+ client.quote(symbol: "BTC/USD")
118
+
119
+ # Available cryptocurrencies
120
+ client.cryptocurrencies
121
+
122
+ # Crypto exchanges
123
+ client.cryptocurrency_exchanges
124
+ ```
125
+
126
+ ### Market Reference Data
54
127
 
55
128
  ```ruby
56
- # 1. response content-type will be :csv
57
- client.quote(symbol: "GOOG", format: :csv)
58
- # 2. assigns custom attachment name
59
- client.timeseries(symbol: "GOOG", interval: "1hour", format: :csv, filename: "google_timeseries_1hour.csv")
60
- # 3. the content-type format will be :json
61
- client.price(symbol: "GOOG")
62
- # 4. the passed apikey is the used in the request payload
63
- client.etd(symbol: "GOOG", apikey: "overrides-whatever-is-the-current-apikey")
64
- # 5. an example of invocation which the API will respond with 401 error code
65
- client.etd(symbol: "GOOG", apikey: "invalid-api-key")
66
- # 6. still exactly the same object with client
67
- TwelvedataRuby.client.api_usage
68
- # 7. an invalid request wherein the required query parameter :interval is missing
69
- TwelvedataRuby.client.timeseries(symbol: "GOOG")
70
- # 8. an invalid request because it contains an invalid parameter
71
- client.price(symbol: "GOOG", invalid_parameter: "value")
72
- # 9. invoking a non-existing API endpoint will cause a NoMethodError exception
73
- client.price(symbol: "GOOG", invalid_parameter: "value")
74
- ```
75
-
76
- All of the invocations possible return instance value is one of the following:
77
- - `TwelvedataRuby::Response` instance object which `#error` instance getter method can return a nil or kind of `TwelvedataRuby::ResponseError` instance if the API, or the API web server responded with some errors. #5 is an example which the API response will have status error with 401 code. `TwelvedataRuby::Response` resolves this into `TwelvedataRuby::UnauthorizedResponseError` instance.
78
- - `TwelvedataRuby::ResponseError` instance object itself when some error occurred that's not coming from the API
79
- - a Hash instance which has an `:errors` key that contains instances of kind `TwelvedataRuby::EndpointError`. This is an invalid request scenario which the #7, #8, and #9 examples. No actual API request was sent in this scenario.
80
-
81
- On first invocation of a valid endpoint name, a `TwelvedataRuby::Client` instance method of the same name is dynamically defined. So in effect, ideally, there can be a one-to-one mapping of all the API endpoints with their respective parameters constraints. Please visit their excellent API documentation to know more of the endpoint details here https://twelvedata.com/doc. Or if you're in a hurry, you can list the endpoints definitions:
129
+ # Available stocks
130
+ client.stocks(exchange: "NASDAQ")
131
+
132
+ # ETF information
133
+ client.etf
134
+
135
+ # Market indices
136
+ client.indices
137
+
138
+ # Stock exchanges
139
+ client.exchanges
140
+
141
+ # Technical indicators
142
+ client.technical_indicators
143
+ ```
144
+
145
+ ### Account & Usage
82
146
 
83
147
  ```ruby
84
- TwelvedataRuby::Endpoint.definitions
148
+ # Check API usage
149
+ usage = client.api_usage
150
+ puts "Current usage: #{usage.parsed_body[:current_usage]}/#{usage.parsed_body[:plan_limit]}"
85
151
  ```
86
152
 
87
- Another way of fetching data from API endpoints is by building a valid `TwelvedataRuby::Request` instance, then invoke `#fetch` on this instance. The possible return values are the same with the above examples.
153
+ ## Advanced Usage
154
+
155
+ ### Response Formats
88
156
 
89
157
  ```ruby
90
- quote_req = TwelvedataRuby::Request.new(:quote, symbol: "IBM")
91
- quote_resp = quote_req.fetch
92
- timeseries_req = TwelvedataRuby::Request.new(:quote, symbol: "IBM", interval: "1hour", format: :csv)
93
- timeseries_resp = timeseries_req.fetch
94
- etd_req = TwelvedataRuby::Request.new(:etd, symbol: "GOOG")
95
- etd_resp = etd_req.fetch
96
- # or just simply chain
97
- price_resp = TwelvedataRuby::Request.new(:price, symbol: "GOOG").fetch
158
+ # JSON response (default)
159
+ response = client.quote(symbol: "AAPL", format: :json)
160
+ data = response.parsed_body # Hash
161
+
162
+ # CSV response
163
+ response = client.quote(symbol: "AAPL", format: :csv)
164
+ table = response.parsed_body # CSV::Table
165
+
166
+ # Save CSV to file
167
+ response = client.time_series(
168
+ symbol: "AAPL",
169
+ interval: "1day",
170
+ format: :csv,
171
+ filename: "apple_daily.csv"
172
+ )
173
+ response.save_to_file("./data/apple_data.csv")
98
174
  ```
99
175
 
100
- An advantage of building a valid request instance first then invoke the `#fetch` on it is you actually have an option to not send the request one by one BUT rather send them to the API server all at once simultaneously (might be in parallel). Like so taking the above examples' request instance objects, send them all simultaneously
176
+ ### Error Handling
101
177
 
102
178
  ```ruby
103
- # returns a 3 element array of Response objects
104
- resp_objects_array = TwelvedataRuby::Client.request(quote_req, timeseries_req, etd_req)
179
+ response = client.quote(symbol: "INVALID")
180
+
181
+ if response.error
182
+ case response.error
183
+ when TwelvedataRuby::UnauthorizedResponseError
184
+ puts "Invalid API key"
185
+ when TwelvedataRuby::NotFoundResponseError
186
+ puts "Symbol not found"
187
+ when TwelvedataRuby::TooManyRequestsResponseError
188
+ puts "Rate limit exceeded"
189
+ else
190
+ puts "Error: #{response.error.message}"
191
+ end
192
+ else
193
+ puts response.parsed_body
194
+ end
105
195
  ```
106
196
 
107
- Be caution that the above example, depending on the number request objects sent and how large the responses, hitting the daily limit is likely possible. But then again if you have several api keys you might be able to supply each request object with its own apikey. :)
197
+ ### Configuration Options
108
198
 
199
+ ```ruby
200
+ client = TwelvedataRuby.client(
201
+ apikey: "your-api-key",
202
+ connect_timeout: 5000, # milliseconds
203
+ apikey_env_var_name: "CUSTOM_API_KEY_VAR"
204
+ )
205
+
206
+ # Update configuration later
207
+ client.configure(connect_timeout: 10000)
208
+
209
+ # Or set individual options
210
+ client.apikey = "new-api-key"
211
+ client.connect_timeout = 3000
212
+ ```
109
213
 
110
- The data from a successful API request can be access from `Response#parsed_body`. If request format is `:json` then it will be a `Hash` instance
214
+ ### Concurrent Requests
111
215
 
112
216
  ```ruby
113
- TwelvedataRuby.client.quote(symbol: "GOOG").parsed_body
114
- =>
115
- {:symbol=>"GOOG",
116
- :name=>"Alphabet Inc",
117
- :exchange=>"NASDAQ",
118
- :currency=>"USD",
119
- :datetime=>"2021-07-15",
120
- :open=>"2650.00000",
121
- :high=>"2651.89990",
122
- :low=>"2611.95996",
123
- :close=>"2625.33008",
124
- :volume=>"828300",
125
- :previous_close=>"2641.64990",
126
- :change=>"-16.31982",
127
- :percent_change=>"-0.61779",
128
- :average_volume=>"850344",
129
- :fifty_two_week=>{:low=>"1406.55005", :high=>"2659.91992", :low_change=>"1218.78003", :high_change=>"-34.58984", :low_change_percent=>"86.65031", :high_change_percent=>"-1.30041", :range=>"1406.550049 - 2659.919922"}}
130
- ```
131
-
132
- Likewise, if the API request format is `:csv` then `Response#parsed_body` will be `CSV#Table` instance
217
+ # Create multiple requests
218
+ requests = [
219
+ TwelvedataRuby::Request.new(:quote, symbol: "AAPL"),
220
+ TwelvedataRuby::Request.new(:quote, symbol: "GOOGL"),
221
+ TwelvedataRuby::Request.new(:quote, symbol: "MSFT")
222
+ ]
223
+
224
+ # Send them concurrently
225
+ responses = TwelvedataRuby::Client.request(requests)
226
+ responses.each_with_index do |http_response, index|
227
+ response = TwelvedataRuby::Response.resolve(http_response, requests[index])
228
+ puts "#{requests[index].query_params[:symbol]}: #{response.parsed_body[:close]}"
229
+ end
230
+ ```
231
+
232
+ ### Complex Data Queries
133
233
 
134
234
  ```ruby
135
- TwelvedataRuby.client.quote(symbol: "GOOG", format: :csv).parsed_body
136
- => #<CSV::Table mode:col_or_row row_count:2>
235
+ # POST request for complex data
236
+ response = client.complex_data(
237
+ symbols: "AAPL,GOOGL,MSFT",
238
+ intervals: "1day,1week",
239
+ start_date: "2024-01-01",
240
+ end_date: "2024-01-31",
241
+ methods: "time_series"
242
+ )
243
+ ```
244
+
245
+ ## Response Objects
246
+
247
+ ### Response Methods
248
+
249
+ ```ruby
250
+ response = client.quote(symbol: "AAPL")
251
+
252
+ # Response status
253
+ response.success? # => true/false
254
+ response.http_status_code # => 200
255
+ response.status_code # => API status code
256
+
257
+ # Content information
258
+ response.content_type # => :json, :csv, :plain
259
+ response.body_bytesize # => response size in bytes
260
+
261
+ # Parsed data
262
+ response.parsed_body # => Hash, CSV::Table, or String
263
+ response.body # => alias for parsed_body
264
+
265
+ # Error information
266
+ response.error # => nil or ResponseError instance
267
+
268
+ # File operations
269
+ response.attachment_filename # => "filename.csv" if present
270
+ response.save_to_file("path/to/file.csv")
271
+ response.dump_parsed_body # => serialized content
272
+
273
+ # Debugging
274
+ response.to_s # => human-readable summary
275
+ response.inspect # => detailed inspection
276
+ ```
277
+
278
+ ### Error Types
279
+
280
+ ```ruby
281
+ # Base error types
282
+ TwelvedataRuby::Error # Base error class
283
+ TwelvedataRuby::ConfigurationError # Configuration issues
284
+ TwelvedataRuby::NetworkError # Network connectivity issues
285
+
286
+ # API endpoint errors
287
+ TwelvedataRuby::EndpointError # Invalid endpoint usage
288
+ TwelvedataRuby::EndpointNameError # Invalid endpoint name
289
+ TwelvedataRuby::EndpointParametersKeysError # Invalid parameters
290
+ TwelvedataRuby::EndpointRequiredParametersError # Missing required parameters
291
+
292
+ # API response errors
293
+ TwelvedataRuby::ResponseError # Base response error
294
+ TwelvedataRuby::BadRequestResponseError # 400 errors
295
+ TwelvedataRuby::UnauthorizedResponseError # 401 errors
296
+ TwelvedataRuby::ForbiddenResponseError # 403 errors
297
+ TwelvedataRuby::NotFoundResponseError # 404 errors
298
+ TwelvedataRuby::TooManyRequestsResponseError # 429 errors
299
+ TwelvedataRuby::InternalServerResponseError # 500 errors
300
+ ```
301
+
302
+ ## Available Endpoints
303
+
304
+ | Endpoint | Method | Required Parameters | Description |
305
+ | -------------------------- | ------ | ------------------------------------------------ | -------------------------- |
306
+ | `quote` | GET | `symbol` | Real-time stock quote |
307
+ | `price` | GET | `symbol` | Current stock price |
308
+ | `time_series` | GET | `symbol`, `interval` | Historical price data |
309
+ | `eod` | GET | `symbol` | End of day price |
310
+ | `exchange_rate` | GET | `symbol` | Forex exchange rate |
311
+ | `currency_conversion` | GET | `symbol`, `amount` | Currency conversion |
312
+ | `symbol_search` | GET | `symbol` | Search for symbols |
313
+ | `earliest_timestamp` | GET | `symbol`, `interval` | Earliest available data |
314
+ | `api_usage` | GET | - | API usage statistics |
315
+ | `stocks` | GET | - | Available stocks |
316
+ | `forex_pairs` | GET | - | Available forex pairs |
317
+ | `cryptocurrencies` | GET | - | Available cryptocurrencies |
318
+ | `etf` | GET | - | Available ETFs |
319
+ | `indices` | GET | - | Available indices |
320
+ | `exchanges` | GET | - | Available exchanges |
321
+ | `cryptocurrency_exchanges` | GET | - | Available crypto exchanges |
322
+ | `technical_indicators` | GET | - | Available indicators |
323
+ | `earnings` | GET | `symbol` | Earnings data |
324
+ | `earnings_calendar` | GET | - | Earnings calendar |
325
+ | `complex_data` | POST | `symbols`, `intervals`, `start_date`, `end_date` | Complex data queries |
326
+
327
+ For complete parameter documentation, visit [Twelve Data's API documentation](https://twelvedata.com/docs).
328
+
329
+ ## Development
330
+
331
+ ### Running Tests
332
+
333
+ ```bash
334
+ # Run all tests
335
+ bundle exec rspec
336
+
337
+ # Run with coverage
338
+ COVERAGE=true bundle exec rspec
339
+
340
+ # Run specific test file
341
+ bundle exec rspec spec/lib/twelvedata_ruby/client_spec.rb
342
+
343
+ # Run with profile information
344
+ PROFILE=true bundle exec rspec
345
+ ```
346
+
347
+ ### Code Quality
348
+
349
+ ```bash
350
+ # Run RuboCop
351
+ bundle exec rubocop
352
+
353
+ # Auto-fix issues
354
+ bundle exec rubocop -A
355
+
356
+ # Generate documentation
357
+ bundle exec yard doc
358
+ ```
359
+
360
+ ### Debugging
361
+
362
+ ```ruby
363
+ # Enable debugging output
364
+ require 'pry'
365
+
366
+ client = TwelvedataRuby.client(apikey: "your-key")
367
+ response = client.quote(symbol: "AAPL")
368
+
369
+ # Debug response
370
+ binding.pry
371
+
372
+ # Inspect request details
373
+ puts response.request.to_h
374
+ puts response.request.full_url
375
+ puts response.request.query_params
137
376
  ```
138
377
 
139
- ## Documentation
140
- You can browse the source code [documentation](https://kanroyalhigh.github.io/twelvedata_ruby/doc/)
141
378
  ## Contributing
142
379
 
143
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/twelvedata_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/twelvedata_ruby/blob/master/CODE_OF_CONDUCT.md).
380
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
381
+
382
+ 1. Fork the repository
383
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
384
+ 3. Make your changes with tests
385
+ 4. Run the test suite (`bundle exec rspec`)
386
+ 5. Run RuboCop (`bundle exec rubocop`)
387
+ 6. Commit your changes (`git commit -am 'Add amazing feature'`)
388
+ 7. Push to the branch (`git push origin feature/amazing-feature`)
389
+ 8. Open a Pull Request
390
+
391
+ ## Release Process
392
+
393
+ #### Quick Release Guide
394
+
395
+ ```bash
396
+ # 1. Prepare release
397
+ bin/release prepare --version 0.4.1
398
+
399
+ # 2. Push changes
400
+ git push origin main
401
+
402
+ # 3. Create GitHub release with tag v0.4.1
403
+ # โ†’ Automatic publication to RubyGems.org via GitHub Actions
404
+ ```
405
+
406
+ #### Release Helper Commands
407
+
408
+ ```bash
409
+ # Check if ready for release
410
+ bin/release check
411
+
412
+ # Auto-bump version
413
+ bin/release bump --type patch # 0.4.0 โ†’ 0.4.1
414
+ bin/release bump --type minor # 0.4.0 โ†’ 0.5.0
415
+ bin/release bump --type major # 0.4.0 โ†’ 1.0.0
416
+
417
+ # Dry run (test without changes)
418
+ bin/release prepare --version 0.4.1 --dry-run
419
+ ```
420
+
421
+ #### GitHub Workflows
422
+
423
+ - **CI**: Runs tests, linting, and security scans on every push/PR
424
+ - **Release**: Automatically publishes to RubyGems.org when GitHub release is created
425
+ - **Documentation**: Updates GitHub Pages with latest API docs
426
+
427
+ #### Manual Release (Advanced)
428
+
429
+ ```bash
430
+ # Trigger release workflow manually
431
+ gh workflow run release.yml \
432
+ --field version=0.4.1 \
433
+ --field dry_run=false
434
+ ```
144
435
 
145
436
  ## License
146
437
 
147
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
438
+ This gem is available as open source under the terms of the [MIT License](LICENSE).
148
439
 
149
440
  ## Code of Conduct
150
441
 
151
- Everyone interacting in the TwelvedataRuby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/twelvedata_ruby/blob/master/CODE_OF_CONDUCT.md).
442
+ Everyone interacting in the TwelvedataRuby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
443
+
444
+ ## Support
445
+
446
+ - ๐Ÿ“– [API Documentation](https://kanutocd.github.io/twelvedata_ruby/doc/)
447
+ - ๐Ÿ› [Issue Tracker](https://github.com/kanutocd/twelvedata_ruby/issues)
448
+ - ๐Ÿ“ง Email: kenneth.c.demanawa@gmail.com
449
+
450
+ ## Changelog
451
+
452
+ See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
453
+
454
+ ## Notice
152
455
 
456
+ This is not an official Twelve Data Ruby library. The author of this gem is not affiliated with Twelve Data in any way, shape or form. Twelve Data APIs and data are Copyright ยฉ 2024 Twelve Data Pte. Ltd.
153
457
 
154
- # Notice
458
+ ---
155
459
 
156
- This is not an offical Twelve Data ruby library and the author of this gem is not affiliated with Twelve Data in any way, shape or form. Twelve Data APIs and data are Copyright ยฉ 2020 Twelve Data Pte. Ltd
460
+ **Made with โค๏ธ by the Ruby community**
data/Rakefile CHANGED
@@ -2,11 +2,117 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
5
6
 
6
- RSpec::Core::RakeTask.new(:spec)
7
+ # RSpec tasks
8
+ RSpec::Core::RakeTask.new(:spec) do |task|
9
+ task.rspec_opts = [
10
+ "--format", "progress",
11
+ "--color",
12
+ "--require", "spec_helper"
13
+ ]
14
+ end
7
15
 
8
- require "rubocop/rake_task"
16
+ # RuboCop tasks
17
+ RuboCop::RakeTask.new(:rubocop) do |task|
18
+ task.options = ["--display-cop-names"]
19
+ end
20
+
21
+ RuboCop::RakeTask.new("rubocop:auto_correct") do |task|
22
+ task.options = ["--auto-correct"]
23
+ end
24
+
25
+ # Quality assurance task
26
+ desc "Run all quality checks"
27
+ task :qa do
28
+ puts "๐Ÿ” Running RuboCop..."
29
+ Rake::Task["rubocop"].invoke
30
+
31
+ puts "\n๐Ÿงช Running tests..."
32
+ Rake::Task["spec"].invoke
33
+
34
+ puts "\nโœ… All quality checks passed!"
35
+ rescue SystemExit => e
36
+ puts "\nโŒ Quality checks failed!"
37
+ exit e.status
38
+ end
39
+
40
+ # Documentation tasks
41
+ begin
42
+ require "yard"
43
+
44
+ YARD::Rake::YardocTask.new(:doc) do |task|
45
+ task.files = ["lib/**/*.rb"]
46
+ task.options = [
47
+ "--markup", "markdown",
48
+ "--markup-provider", "kramdown",
49
+ "--main", "README.md",
50
+ "--output-dir", "doc"
51
+ ]
52
+ end
53
+
54
+ desc "Generate and open documentation"
55
+ task docs: :doc do
56
+ system("open doc/index.html") if RUBY_PLATFORM.include?("darwin")
57
+ end
58
+ rescue LoadError
59
+ puts "YARD not available. Install it with: gem install yard"
60
+ end
61
+
62
+ # Coverage task
63
+ desc "Run tests with coverage report"
64
+ task :coverage do
65
+ ENV["COVERAGE"] = "true"
66
+ Rake::Task["spec"].invoke
67
+ end
68
+
69
+ # Development setup task
70
+ desc "Set up development environment"
71
+ task :setup do
72
+ puts "๐Ÿ“ฆ Installing dependencies..."
73
+ system("bundle install")
74
+
75
+ puts "๐Ÿ”ง Setting up git hooks..."
76
+ setup_git_hooks
77
+
78
+ puts "โœ… Development environment ready!"
79
+ end
80
+
81
+ # Release preparation task
82
+ desc "Prepare for release"
83
+ task :release_prep do
84
+ puts "๐Ÿ” Running quality checks..."
85
+ Rake::Task["qa"].invoke
86
+
87
+ puts "๐Ÿ“š Generating documentation..."
88
+ Rake::Task["doc"].invoke if defined?(YARD)
89
+
90
+ puts "โœ… Ready for release!"
91
+ end
92
+
93
+ # Console task for development
94
+ desc "Start interactive console with gem loaded"
95
+ task :console do
96
+ require "irb"
97
+ require "twelvedata_ruby"
98
+ ARGV.clear
99
+ IRB.start
100
+ end
101
+
102
+ # Default task
103
+ task default: :qa
104
+
105
+ # Helper methods
106
+ def setup_git_hooks
107
+ hooks_dir = File.join(__dir__, ".git", "hooks")
108
+ return unless Dir.exist?(hooks_dir)
9
109
 
10
- RuboCop::RakeTask.new
110
+ pre_commit_hook = File.join(hooks_dir, "pre-commit")
111
+ File.write(pre_commit_hook, <<~HOOK)
112
+ #!/bin/sh
113
+ echo "Running pre-commit checks..."
114
+ bundle exec rubocop --format simple
115
+ HOOK
11
116
 
12
- task default: %i[spec rubocop]
117
+ File.chmod(0o755, pre_commit_hook) if File.exist?(pre_commit_hook)
118
+ end