durable_huggingface_hub 0.2.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.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +29 -0
  3. data/.rubocop.yml +108 -0
  4. data/CHANGELOG.md +127 -0
  5. data/README.md +547 -0
  6. data/Rakefile +106 -0
  7. data/devenv.lock +171 -0
  8. data/devenv.nix +15 -0
  9. data/devenv.yaml +8 -0
  10. data/huggingface_hub.gemspec +63 -0
  11. data/lib/durable_huggingface_hub/authentication.rb +245 -0
  12. data/lib/durable_huggingface_hub/cache.rb +508 -0
  13. data/lib/durable_huggingface_hub/configuration.rb +191 -0
  14. data/lib/durable_huggingface_hub/constants.rb +145 -0
  15. data/lib/durable_huggingface_hub/errors.rb +412 -0
  16. data/lib/durable_huggingface_hub/file_download.rb +831 -0
  17. data/lib/durable_huggingface_hub/hf_api.rb +1278 -0
  18. data/lib/durable_huggingface_hub/repo_card.rb +430 -0
  19. data/lib/durable_huggingface_hub/types/cache_info.rb +298 -0
  20. data/lib/durable_huggingface_hub/types/commit_info.rb +149 -0
  21. data/lib/durable_huggingface_hub/types/dataset_info.rb +158 -0
  22. data/lib/durable_huggingface_hub/types/model_info.rb +154 -0
  23. data/lib/durable_huggingface_hub/types/space_info.rb +158 -0
  24. data/lib/durable_huggingface_hub/types/user.rb +179 -0
  25. data/lib/durable_huggingface_hub/types.rb +205 -0
  26. data/lib/durable_huggingface_hub/utils/auth.rb +174 -0
  27. data/lib/durable_huggingface_hub/utils/headers.rb +220 -0
  28. data/lib/durable_huggingface_hub/utils/http.rb +329 -0
  29. data/lib/durable_huggingface_hub/utils/paths.rb +230 -0
  30. data/lib/durable_huggingface_hub/utils/progress.rb +217 -0
  31. data/lib/durable_huggingface_hub/utils/retry.rb +165 -0
  32. data/lib/durable_huggingface_hub/utils/validators.rb +236 -0
  33. data/lib/durable_huggingface_hub/version.rb +8 -0
  34. data/lib/huggingface_hub.rb +205 -0
  35. metadata +334 -0
data/README.md ADDED
@@ -0,0 +1,547 @@
1
+ # HuggingFace Hub Ruby
2
+
3
+ A pure Ruby implementation of the HuggingFace Hub client library. This library provides a complete, production-ready interface to HuggingFace Hub for downloading models, datasets, and managing repositories - with zero Python dependencies.
4
+
5
+ ## Features
6
+
7
+ - **Pure Ruby Implementation**: No Python required - runs entirely in Ruby
8
+ - **Complete Hub API**: Download models, datasets, and manage repositories
9
+ - **Smart Caching**: ETag-based validation with symlink optimization for storage efficiency
10
+ - **Authentication**: Full token management with multiple authentication methods
11
+ - **Progress Tracking**: Built-in progress bars for uploads and downloads
12
+ - **Offline Mode**: Work with cached models when offline
13
+ - **Repository Management**: Create, delete, and manage Hub repositories
14
+ - **File Operations**: Upload, download, and delete files with LFS support
15
+ - **Model Cards**: Read and write model, dataset, and space cards
16
+ - **Production Ready**: Comprehensive error handling, retries, and logging
17
+ - **Type Safe**: Validation and type checking throughout
18
+ - **Well Documented**: Extensive API documentation and usage examples
19
+
20
+ ## Quick Start
21
+
22
+ ```ruby
23
+ require 'huggingface_hub'
24
+
25
+ # Download a file from a model repository
26
+ HuggingfaceHub.hf_hub_download(
27
+ repo_id: 'gpt2',
28
+ filename: 'config.json'
29
+ )
30
+
31
+ # Or use the API client directly
32
+ api = HuggingfaceHub::HfApi.new
33
+ models = api.list_models(filter: 'text-generation')
34
+ ```
35
+
36
+ ## Installation
37
+
38
+ Add this line to your application's Gemfile:
39
+
40
+ ```ruby
41
+ gem 'huggingface_hub'
42
+ ```
43
+
44
+ And then execute:
45
+
46
+ ```bash
47
+ bundle install
48
+ ```
49
+
50
+ Or install it yourself as:
51
+
52
+ ```bash
53
+ gem install huggingface_hub
54
+ ```
55
+
56
+ ## Requirements
57
+
58
+ - Ruby 3.0 or higher
59
+ - No Python dependencies required
60
+
61
+ ## Usage
62
+
63
+ ### Downloading Files
64
+
65
+ Download a specific file from a repository:
66
+
67
+ ```ruby
68
+ require 'huggingface_hub'
69
+
70
+ # Download a model configuration file
71
+ config_path = HuggingfaceHub.hf_hub_download(
72
+ repo_id: 'bert-base-uncased',
73
+ filename: 'config.json'
74
+ )
75
+
76
+ # Download from a specific revision
77
+ model_path = HuggingfaceHub.hf_hub_download(
78
+ repo_id: 'gpt2',
79
+ filename: 'pytorch_model.bin',
80
+ revision: 'main'
81
+ )
82
+
83
+ # Download with authentication
84
+ private_file = HuggingfaceHub.hf_hub_download(
85
+ repo_id: 'private/model',
86
+ filename: 'model.safetensors',
87
+ token: ENV['HF_TOKEN']
88
+ )
89
+ ```
90
+
91
+ ### Downloading Entire Repositories
92
+
93
+ Download all files from a repository:
94
+
95
+ ```ruby
96
+ # Download entire model repository
97
+ local_dir = HuggingfaceHub.snapshot_download(
98
+ repo_id: 'gpt2',
99
+ revision: 'main'
100
+ )
101
+
102
+ # Download only specific file patterns
103
+ filtered_dir = HuggingfaceHub.snapshot_download(
104
+ repo_id: 'bert-base-uncased',
105
+ allow_patterns: ['*.json', '*.txt'],
106
+ ignore_patterns: ['*.bin']
107
+ )
108
+ ```
109
+
110
+ ### Authentication
111
+
112
+ Multiple ways to authenticate:
113
+
114
+ ```ruby
115
+ # Login interactively
116
+ HuggingfaceHub.login
117
+
118
+ # Login with token
119
+ HuggingfaceHub.login(token: 'hf_...')
120
+
121
+ # Use environment variable
122
+ ENV['HF_TOKEN'] = 'hf_...'
123
+
124
+ # Pass token directly to API calls
125
+ api = HuggingfaceHub::HfApi.new(token: 'hf_...')
126
+
127
+ # Check current user
128
+ user_info = api.whoami
129
+ puts "Logged in as: #{user_info['name']}"
130
+ ```
131
+
132
+ ### Repository Management
133
+
134
+ Create and manage repositories:
135
+
136
+ ```ruby
137
+ api = HuggingfaceHub::HfApi.new
138
+
139
+ # Create a new model repository
140
+ url = api.create_repo(
141
+ repo_id: 'my-awesome-model',
142
+ repo_type: 'model',
143
+ private: false
144
+ )
145
+
146
+ # Check if repository exists
147
+ exists = api.repo_exists(repo_id: 'my-awesome-model')
148
+
149
+ # Get repository information
150
+ info = api.model_info(repo_id: 'gpt2')
151
+ puts "Model tags: #{info.tags}"
152
+ puts "Last modified: #{info.last_modified}"
153
+
154
+ # Delete a repository
155
+ api.delete_repo(repo_id: 'my-test-model')
156
+ ```
157
+
158
+ ### File Operations
159
+
160
+ Upload and manage files in repositories:
161
+
162
+ ```ruby
163
+ api = HuggingfaceHub::HfApi.new
164
+
165
+ # Upload a single file
166
+ api.upload_file(
167
+ path_or_fileobj: './model.safetensors',
168
+ path_in_repo: 'model.safetensors',
169
+ repo_id: 'my-model'
170
+ )
171
+
172
+ # Upload an entire folder
173
+ api.upload_folder(
174
+ folder_path: './my-model',
175
+ repo_id: 'my-model',
176
+ commit_message: 'Upload complete model'
177
+ )
178
+
179
+ # Delete a file
180
+ api.delete_file(
181
+ path_in_repo: 'old_model.bin',
182
+ repo_id: 'my-model'
183
+ )
184
+
185
+ # List files in a repository
186
+ files = api.list_repo_files(
187
+ repo_id: 'gpt2',
188
+ revision: 'main'
189
+ )
190
+ ```
191
+
192
+ ### Searching and Listing
193
+
194
+ Find models, datasets, and spaces:
195
+
196
+ ```ruby
197
+ api = HuggingfaceHub::HfApi.new
198
+
199
+ # List all text generation models
200
+ models = api.list_models(
201
+ filter: 'text-generation',
202
+ sort: 'downloads',
203
+ limit: 10
204
+ )
205
+
206
+ models.each do |model|
207
+ puts "#{model.id} - #{model.downloads} downloads"
208
+ end
209
+
210
+ # List datasets
211
+ datasets = api.list_datasets(
212
+ filter: 'translation',
213
+ language: 'en'
214
+ )
215
+
216
+ # List spaces
217
+ spaces = api.list_spaces(
218
+ filter: 'gradio',
219
+ limit: 5
220
+ )
221
+ ```
222
+
223
+ ### Working with Model Cards
224
+
225
+ Read and write repository cards:
226
+
227
+ ```ruby
228
+ # Load a model card
229
+ card = HuggingfaceHub::ModelCard.load(repo_id: 'gpt2')
230
+ puts card.data.tags
231
+ puts card.text
232
+
233
+ # Create a new model card
234
+ card = HuggingfaceHub::ModelCard.new(
235
+ text: "# My Model\n\nThis is my awesome model.",
236
+ data: {
237
+ language: 'en',
238
+ license: 'apache-2.0',
239
+ tags: ['text-generation']
240
+ }
241
+ )
242
+
243
+ # Save to repository
244
+ card.push_to_hub(repo_id: 'my-model')
245
+ ```
246
+
247
+ ### Caching and Offline Mode
248
+
249
+ Control caching behavior:
250
+
251
+ ```ruby
252
+ # Specify custom cache directory
253
+ HuggingfaceHub.config.cache_dir = '/path/to/cache'
254
+
255
+ # Enable offline mode (only use cached files)
256
+ HuggingfaceHub.config.offline = true
257
+
258
+ # Scan cache to see what's stored
259
+ cache_info = HuggingfaceHub.scan_cache_dir
260
+
261
+ cache_info.repos.each do |repo|
262
+ puts "#{repo.repo_id}: #{repo.size_on_disk_str}"
263
+ end
264
+
265
+ # Clean up cache
266
+ strategy = cache_info.delete_revisions(*old_revisions)
267
+ strategy.execute
268
+ ```
269
+
270
+ ### Error Handling
271
+
272
+ The library provides detailed error messages:
273
+
274
+ ```ruby
275
+ begin
276
+ HuggingfaceHub.hf_hub_download(
277
+ repo_id: 'nonexistent/model',
278
+ filename: 'config.json'
279
+ )
280
+ rescue HuggingfaceHub::RepositoryNotFoundError => e
281
+ puts "Repository not found: #{e.message}"
282
+ rescue HuggingfaceHub::RevisionNotFoundError => e
283
+ puts "Revision not found: #{e.message}"
284
+ rescue HuggingfaceHub::EntryNotFoundError => e
285
+ puts "File not found: #{e.message}"
286
+ rescue HuggingfaceHub::HfHubHTTPError => e
287
+ puts "HTTP error: #{e.message}"
288
+ puts "Status code: #{e.response.status}"
289
+ end
290
+ ```
291
+
292
+ ### Configuration
293
+
294
+ Configure library behavior via environment variables:
295
+
296
+ ```bash
297
+ # Authentication
298
+ export HF_TOKEN='hf_...'
299
+
300
+ # Cache location
301
+ export HF_HOME=~/.cache/huggingface
302
+ export HF_HUB_CACHE=~/.cache/huggingface/hub
303
+
304
+ # Hub endpoint (for custom/enterprise instances)
305
+ export HF_ENDPOINT=https://huggingface.co
306
+
307
+ # Behavior
308
+ export HF_HUB_OFFLINE=1 # Enable offline mode
309
+ export HF_HUB_DISABLE_PROGRESS_BARS=1 # Hide progress bars
310
+ export HF_HUB_DISABLE_TELEMETRY=1 # Opt out of telemetry
311
+ ```
312
+
313
+ Or configure programmatically:
314
+
315
+ ```ruby
316
+ HuggingfaceHub.configure do |config|
317
+ config.cache_dir = '/custom/cache/path'
318
+ config.endpoint = 'https://huggingface.co'
319
+ config.offline = false
320
+ config.progress_bars = true
321
+ config.token = ENV['HF_TOKEN']
322
+ end
323
+ ```
324
+
325
+ ## API Reference
326
+
327
+ See the [API Documentation](https://rubydoc.info/gems/huggingface_hub) for complete reference.
328
+
329
+ ### Core Classes
330
+
331
+ - **HfApi**: Main API client for all Hub operations
332
+ - **ModelCard**, **DatasetCard**, **SpaceCard**: Repository card management
333
+ - **CacheManager**: Cache inspection and cleanup
334
+
335
+ ### Core Functions
336
+
337
+ - `hf_hub_download`: Download a single file from a repository
338
+ - `snapshot_download`: Download an entire repository
339
+ - `login`/`logout`: Authentication management
340
+ - `scan_cache_dir`: Inspect cached files
341
+
342
+ ## Architecture
343
+
344
+ The library is organized into modular components:
345
+
346
+ ```
347
+ lib/durable_huggingface_hub/
348
+ ├── hf_api.rb # Main API client
349
+ ├── file_download.rb # Download utilities
350
+ ├── constants.rb # Configuration constants
351
+ ├── errors.rb # Error hierarchy
352
+ ├── authentication.rb # Token management
353
+ ├── cache.rb # Caching system
354
+ ├── repository_card.rb # Model/dataset cards
355
+ └── utils/ # Utility modules
356
+ ```
357
+
358
+ ## Design Philosophy
359
+
360
+ This library follows Durable Programming's core principles:
361
+
362
+ - **Pragmatic Problem-Solving**: Solve real-world ML deployment needs with practical solutions
363
+ - **Sustainability**: Design for long-term maintenance and evolution
364
+ - **Quality**: Comprehensive testing, validation, and error handling
365
+ - **Transparency**: Clear documentation and honest capability representation
366
+ - **Incremental Improvement**: Build on proven patterns from the Python implementation
367
+
368
+ ## Feature Comparison with Python Client
369
+
370
+ This Ruby implementation aims to provide feature parity with the official Python `huggingface_hub` library while following Ruby conventions. The table below tracks implementation progress:
371
+
372
+ ### Core Features
373
+
374
+ | Feature | Python | Ruby | Status |
375
+ |---------|--------|------|--------|
376
+ | **File Operations** |
377
+ | Download single file (`hf_hub_download`) | ✓ | ✓ | Complete |
378
+ | Download repository snapshot | ✓ | ✓ | Complete |
379
+ | Upload single file | ✓ | ✓ | Complete |
380
+ | Upload folder | ✓ | ✓ | Complete |
381
+ | Delete files | ✓ | ✓ | Complete |
382
+ | **Authentication** |
383
+ | Token management | ✓ | ✓ | Complete |
384
+ | Login/logout | ✓ | ✓ | Complete |
385
+ | User info (`whoami`) | ✓ | ✓ | Complete |
386
+ | Git credential integration | ✓ | ✓ | Complete |
387
+ | **Repository Management** |
388
+ | Create repository | ✓ | ✓ | Complete |
389
+ | Delete repository | ✓ | ✓ | Complete |
390
+ | Update repository visibility | ✓ | ✓ | Complete |
391
+ | Repository info | ✓ | ✓ | Complete |
392
+ | Check repository exists | ✓ | ✓ | Complete |
393
+ | List repository files | ✓ | ✓ | Complete |
394
+ | **Search & Discovery** |
395
+ | List models | ✓ | ✓ | Complete |
396
+ | List datasets | ✓ | ✓ | Complete |
397
+ | List spaces | ✓ | ✓ | Complete |
398
+ | Filter by tags/author | ✓ | ✓ | Complete |
399
+ | **Cache Management** |
400
+ | Scan cache directory | ✓ | ✓ | Complete |
401
+ | Delete cached revisions | ✓ | ✓ | Complete |
402
+ | Cache info dataclasses | ✓ | ✓ | Complete |
403
+ | **Repository Cards** |
404
+ | Load model cards | ✓ | ✓ | Complete |
405
+ | Create model cards | ✓ | ✓ | Complete |
406
+ | Update model cards | ✓ | ✓ | Complete |
407
+ | Dataset cards | ✓ | ✓ | Complete |
408
+ | Space cards | ✓ | ✓ | Complete |
409
+
410
+ ### Advanced Features
411
+
412
+ | Feature | Python | Ruby | Status |
413
+ |---------|--------|------|--------|
414
+ | **Inference** |
415
+ | Inference client | ✓ | ✗ | Not planned v1.0 |
416
+ | Inference endpoints | ✓ | ✗ | Not planned v1.0 |
417
+ | **Community Features** |
418
+ | Discussions | ✓ | ✗ | Not planned v1.0 |
419
+ | Pull requests | ✓ | ✗ | Not planned v1.0 |
420
+ | Comments | ✓ | ✗ | Not planned v1.0 |
421
+ | **Spaces** |
422
+ | Runtime management | ✓ | ✗ | Not planned v1.0 |
423
+ | Secrets management | ✓ | ✗ | Not planned v1.0 |
424
+ | Hardware requests | ✓ | ✗ | Not planned v1.0 |
425
+ | **Other** |
426
+ | Webhooks server | ✓ | ✗ | Not planned v1.0 |
427
+ | Collections | ✓ | ✗ | Not planned v1.0 |
428
+ | OAuth | ✓ | ✗ | Not planned v1.0 |
429
+ | HfFileSystem (fsspec) | ✓ | ✗ | Not planned v1.0 |
430
+ | TensorBoard integration | ✓ | ✗ | Not planned v1.0 |
431
+
432
+ **Legend:**
433
+ - ✓ Implemented
434
+ - ⚠️ Planned for v1.0
435
+ - ✗ Not planned for v1.0
436
+
437
+ The Ruby implementation focuses on core functionality that Ruby developers need for downloading models and datasets, managing repositories, and basic Hub interactions. Advanced features like inference clients and community features may be added in future versions based on community feedback.
438
+
439
+ ## Ruby-Specific Design Choices
440
+
441
+ While maintaining API compatibility where practical, this Ruby implementation:
442
+
443
+ - Uses Ruby idioms and conventions (snake_case, blocks, keyword arguments)
444
+ - Leverages Ruby's standard library for HTTP and file operations
445
+ - Employs Ruby-native gems for validation and type checking
446
+ - Provides Ruby-friendly error handling with proper exception hierarchy
447
+ - Uses Ruby's module system for code organization
448
+ - Follows Ruby community standards for gem structure and distribution
449
+
450
+ ## Contributing
451
+
452
+ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for:
453
+
454
+ - Development setup instructions
455
+ - Code style guidelines
456
+ - Testing requirements
457
+ - Pull request process
458
+
459
+ ## Development
460
+
461
+ Clone the repository:
462
+
463
+ ```bash
464
+ git clone https://github.com/durableprogramming/huggingface-hub-ruby.git
465
+ cd huggingface-hub-ruby
466
+ ```
467
+
468
+ Install dependencies:
469
+
470
+ ```bash
471
+ bundle install
472
+ ```
473
+
474
+ Run tests:
475
+
476
+ ```bash
477
+ bundle exec rake test
478
+ ```
479
+
480
+ Run linter:
481
+
482
+ ```bash
483
+ bundle exec rubocop
484
+ ```
485
+
486
+ ## Testing
487
+
488
+ The library includes comprehensive tests:
489
+
490
+ ```bash
491
+ # Run all tests
492
+ bundle exec rake test
493
+
494
+ # Run specific test file
495
+ bundle exec ruby test/huggingface_hub/hf_api_test.rb
496
+
497
+ # Run with coverage
498
+ bundle exec rake test:coverage
499
+ ```
500
+
501
+ ## License
502
+
503
+ MIT License - see [LICENSE](LICENSE) file for details.
504
+
505
+ ## Acknowledgments
506
+
507
+ This is a pure Ruby port of the [HuggingFace Hub Python library](https://github.com/huggingface/huggingface_hub). We are grateful to the HuggingFace team for creating the original library and for their contributions to open-source AI tooling.
508
+
509
+ ## Support
510
+
511
+ - Documentation: [https://rubydoc.info/gems/huggingface_hub](https://rubydoc.info/gems/huggingface_hub)
512
+ - Issues: [GitHub Issues](https://github.com/durableprogramming/huggingface-hub-ruby/issues)
513
+ - Email: commercial@durableprogramming.com
514
+
515
+ ## Roadmap
516
+
517
+ ### v0.2.0 (Current) - Feature Complete ✓
518
+ - ✓ Constants and configuration
519
+ - ✓ Error hierarchy
520
+ - ✓ Authentication (login, logout, whoami)
521
+ - ✓ File download with caching
522
+ - ✓ File upload operations (single file and folders)
523
+ - ✓ Repository creation, deletion, and management
524
+ - ✓ Repository information (models, datasets, spaces)
525
+ - ✓ Search and listing (models, datasets, spaces)
526
+ - ✓ Repository cards (model, dataset, space)
527
+ - ✓ Complete cache management with deletion support
528
+ - ✓ LFS detection and handling
529
+
530
+ ### Planned for v1.0.0
531
+ - [ ] Additional repository management features (move, duplicate, update settings)
532
+ - [ ] Comprehensive integration testing with live Hub
533
+ - [ ] Production-ready error handling and retry logic
534
+ - [ ] Performance optimizations
535
+ - [ ] Complete documentation and usage examples
536
+
537
+ ### Future Considerations
538
+ Advanced features from the Python client may be added based on community needs:
539
+ - Inference client and endpoints
540
+ - Community features (discussions, PRs)
541
+ - Spaces runtime management
542
+ - Webhooks and collections
543
+ - OAuth integration
544
+
545
+ ## Changelog
546
+
547
+ See [CHANGELOG.md](CHANGELOG.md) for version history and release notes.
data/Rakefile ADDED
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+ require "rubocop/rake_task"
6
+
7
+ # Test tasks
8
+ Rake::TestTask.new(:test) do |t|
9
+ t.libs << "test"
10
+ t.libs << "lib"
11
+ t.test_files = FileList["test/**/*_test.rb"]
12
+ t.verbose = true
13
+ t.warning = false
14
+ end
15
+
16
+ namespace :test do
17
+ desc "Run tests with coverage"
18
+ task :coverage do
19
+ ENV["COVERAGE"] = "true"
20
+ Rake::Task[:test].execute
21
+ end
22
+
23
+ desc "Run integration tests"
24
+ Rake::TestTask.new(:integration) do |t|
25
+ t.libs << "test"
26
+ t.libs << "lib"
27
+ t.test_files = FileList["test/integration/**/*_test.rb"]
28
+ t.verbose = true
29
+ t.warning = false
30
+ end
31
+ end
32
+
33
+ # RuboCop tasks
34
+ RuboCop::RakeTask.new do |task|
35
+ task.options = ["--display-cop-names"]
36
+ task.fail_on_error = true
37
+ end
38
+
39
+ namespace :rubocop do
40
+ desc "Auto-correct RuboCop offenses"
41
+ RuboCop::RakeTask.new(:autocorrect) do |task|
42
+ task.options = ["--auto-correct", "--display-cop-names"]
43
+ end
44
+
45
+ desc "Auto-correct RuboCop offenses (including unsafe)"
46
+ RuboCop::RakeTask.new(:autocorrect_all) do |task|
47
+ task.options = ["--auto-correct-all", "--display-cop-names"]
48
+ end
49
+ end
50
+
51
+ # YARD documentation tasks
52
+ begin
53
+ require "yard"
54
+
55
+ YARD::Rake::YardocTask.new(:yard) do |t|
56
+ t.files = ["lib/**/*.rb"]
57
+ t.options = ["--output-dir", "doc", "--readme", "README.md"]
58
+ end
59
+
60
+ namespace :yard do
61
+ desc "Generate YARD documentation and open in browser"
62
+ task :server do
63
+ sh "yard server --reload"
64
+ end
65
+
66
+ desc "List undocumented objects"
67
+ task :stats do
68
+ sh "yard stats --list-undoc"
69
+ end
70
+ end
71
+ rescue LoadError
72
+ # YARD not available
73
+ end
74
+
75
+ # Default task
76
+ task default: %i[rubocop test]
77
+
78
+ # Build task
79
+ desc "Build the gem"
80
+ task :build do
81
+ sh "gem build huggingface_hub.gemspec"
82
+ end
83
+
84
+ # Install task
85
+ desc "Build and install the gem locally"
86
+ task install: :build do
87
+ sh "gem install huggingface_hub-*.gem"
88
+ end
89
+
90
+ # Clean task
91
+ desc "Clean up generated files"
92
+ task :clean do
93
+ sh "rm -f huggingface_hub-*.gem"
94
+ sh "rm -rf doc/"
95
+ sh "rm -rf coverage/"
96
+ sh "rm -rf tmp/"
97
+ end
98
+
99
+ # Console task for interactive testing
100
+ desc "Open an IRB console with the gem loaded"
101
+ task :console do
102
+ require "irb"
103
+ require "huggingface_hub"
104
+ ARGV.clear
105
+ IRB.start
106
+ end