taski 0.2.0 → 0.2.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b66b9afd145af8c5a07839b1886212336ffbdcb935897a278afae10315162e8
4
- data.tar.gz: 7f43e874932671c2a41adc776514022e7d44d9ec0018935e2bd2e7e4d4537543
3
+ metadata.gz: 4e44ea93464ceaf8994d761cec75cf4d32df7cdb8f90d25b4cfcae5be7f8a586
4
+ data.tar.gz: 8a1b5fae85bbffb28756f2e13b3f98c2cb8023c76346b5da722ac55e87ef3cc5
5
5
  SHA512:
6
- metadata.gz: 8175467340490afdd0e9f1d4ba5c2e3db257e7d4c62850f88a138676056ea140753e2c38042803dd46c6c071731245314c2b597af83eb8c237be28d20e998e60
7
- data.tar.gz: d1695488ca402cdb18800bd4b8623c64ed3c681a5dd6039c651c117c99793045fa59cca85f82cde0fde311b0ada0d81b8a66ba4d8cbb9b576ebe00fe71e760cf
6
+ metadata.gz: '037285b1bc19edd6d674f6748674fa8443c0cb40d5199de86bdfa3696c1597308d69ff5236a7114c43cf666a27e62f5c4111c5a36301736c4fdac98cdd65b4c4'
7
+ data.tar.gz: afa967d630b56f9de1f4974879533572d06c42d574dce6bea69da9635ce69e06251af555168ff0b3475e95d5a1d6d07e8951e6052f0f6e04291d07b15d23239b
data/.standard.yml ADDED
@@ -0,0 +1,9 @@
1
+ ruby_version: 3.2
2
+
3
+ ignore:
4
+ - 'pkg/**/*'
5
+ - 'vendor/**/*'
6
+ - 'bin/**/*'
7
+
8
+ # Allow eval for dynamic method creation in define API
9
+ parallel: true
data/README.md CHANGED
@@ -1,27 +1,21 @@
1
1
  # Taski
2
2
 
3
- > **🚧 Development Status:** Taski is currently under active development and the API may change. Not yet recommended for production use.
3
+ [![CI](https://github.com/ahogappa/taski/workflows/CI/badge.svg)](https://github.com/ahogappa/taski/actions/workflows/ci.yml)
4
+ [![Codecov](https://codecov.io/gh/ahogappa/taski/branch/master/graph/badge.svg)](https://codecov.io/gh/ahogappa/taski)
5
+ [![Gem Version](https://badge.fury.io/rb/taski.svg)](https://badge.fury.io/rb/taski)
4
6
 
5
- **Taski** is a powerful Ruby framework for building task dependency graphs with automatic resolution and execution. It provides two complementary APIs for different use cases: static dependencies through exports and dynamic dependencies through define.
7
+ > **🚧 Development Status:** Taski is currently under active development. Not yet recommended for production use.
6
8
 
7
- ## 🎯 Key Features
9
+ **Taski** is a Ruby framework for building task dependency graphs with automatic resolution and execution. It provides two APIs: static dependencies through **Exports** and dynamic dependencies through **Define**.
8
10
 
9
- - **Automatic Dependency Resolution**: Dependencies are detected automatically through static analysis and runtime evaluation
10
- - **Two Complementary APIs**: Choose the right approach for your use case
11
- - **Exports API**: For simple, static dependencies
12
- - **Define API**: For complex, dynamic dependencies based on runtime conditions
13
- - **Thread-Safe Execution**: Safe for concurrent access with Monitor-based synchronization
14
- - **Circular Dependency Detection**: Prevents infinite loops with clear error messages
15
- - **Memory Leak Prevention**: Built-in reset mechanisms for long-running applications
16
- - **Topological Execution**: Tasks execute in correct dependency order automatically
17
- - **Reverse Cleanup**: Clean operations run in reverse dependency order
11
+ > **Name Origin**: "Taski" comes from the Japanese word "襷" (tasuki), a sash used in relay races. Just like how runners pass the sash to the next teammate, tasks in Taski pass dependencies to one another in a continuous chain.
18
12
 
19
13
  ## 🚀 Quick Start
20
14
 
21
15
  ```ruby
22
16
  require 'taski'
23
17
 
24
- # Simple static dependency using Exports API
18
+ # Static dependency using Exports API
25
19
  class DatabaseSetup < Taski::Task
26
20
  exports :connection_string
27
21
 
@@ -32,16 +26,11 @@ class DatabaseSetup < Taski::Task
32
26
  end
33
27
 
34
28
  class APIServer < Taski::Task
35
- exports :port
36
-
37
29
  def build
38
- # Automatic dependency: DatabaseSetup will be built first
39
30
  puts "Starting API with #{DatabaseSetup.connection_string}"
40
- @port = 3000
41
31
  end
42
32
  end
43
33
 
44
- # Execute - dependencies are resolved automatically
45
34
  APIServer.build
46
35
  # => Database configured
47
36
  # => Starting API with postgresql://localhost/myapp
@@ -51,7 +40,7 @@ APIServer.build
51
40
 
52
41
  ### Exports API - Static Dependencies
53
42
 
54
- Use the **Exports API** when you have simple, predictable dependencies:
43
+ For simple, predictable dependencies:
55
44
 
56
45
  ```ruby
57
46
  class ConfigLoader < Taski::Task
@@ -60,274 +49,177 @@ class ConfigLoader < Taski::Task
60
49
  def build
61
50
  @app_name = "MyApp"
62
51
  @version = "1.0.0"
52
+ puts "Config loaded: #{@app_name} v#{@version}"
63
53
  end
64
54
  end
65
55
 
66
56
  class Deployment < Taski::Task
67
- exports :deploy_url
68
-
69
57
  def build
70
- # Static dependency - always uses ConfigLoader
71
58
  @deploy_url = "https://#{ConfigLoader.app_name}.example.com"
59
+ puts "Deploying to #{@deploy_url}"
72
60
  end
73
61
  end
62
+
63
+ Deployment.build
64
+ # => Config loaded: MyApp v1.0.0
65
+ # => Deploying to https://MyApp.example.com
74
66
  ```
75
67
 
76
68
  ### Define API - Dynamic Dependencies
77
69
 
78
- Use the **Define API** when dependencies change based on runtime conditions:
70
+ For dependencies that change based on runtime conditions:
79
71
 
80
72
  ```ruby
81
73
  class EnvironmentConfig < Taski::Task
82
74
  define :database_service, -> {
83
- # Dynamic dependency based on environment
84
75
  case ENV['RAILS_ENV']
85
76
  when 'production'
86
- ProductionDatabase.setup
87
- when 'staging'
88
- StagingDatabase.setup
89
- else
90
- DevelopmentDatabase.setup
91
- end
92
- }
93
-
94
- define :cache_strategy, -> {
95
- # Dynamic dependency based on feature flags
96
- if FeatureFlag.enabled?(:redis_cache)
97
- RedisCache.configure
77
+ "production-db.example.com"
98
78
  else
99
- MemoryCache.configure
79
+ "localhost:5432"
100
80
  end
101
81
  }
102
82
 
103
83
  def build
104
- puts "Using #{database_service}"
105
- puts "Cache: #{cache_strategy}"
84
+ puts "Using database: #{database_service}"
85
+ puts "Environment: #{ENV['RAILS_ENV'] || 'development'}"
106
86
  end
107
87
  end
108
- ```
109
88
 
110
- > **⚠️ Note:** The `define` API uses dynamic method definition, which may generate Ruby warnings about method redefinition. This is expected behavior due to the dependency resolution mechanism and does not affect functionality.
89
+ EnvironmentConfig.build
90
+ # => Using database: localhost:5432
91
+ # => Environment: development
92
+
93
+ ENV['RAILS_ENV'] = 'production'
94
+ EnvironmentConfig.reset!
95
+ EnvironmentConfig.build
96
+ # => Using database: production-db.example.com
97
+ # => Environment: production
98
+ ```
111
99
 
112
100
  ### When to Use Each API
113
101
 
114
- | Use Case | Recommended API | Example |
115
- |----------|----------------|---------|
116
- | Simple value exports | Exports API | Configuration values, file paths |
117
- | Environment-specific logic | Define API | Different services per environment |
118
- | Feature flag dependencies | Define API | Optional components based on flags |
119
- | Conditional processing | Define API | Different algorithms based on input |
120
- | Static file dependencies | Exports API | Build artifacts, compiled assets |
102
+ - **Define API**: Best for dynamic runtime dependencies. Cannot contain side effects in definition blocks.
103
+ - **Exports API**: Ideal for static dependencies. Supports side effects in build methods.
121
104
 
122
- ## 🔧 Advanced Features
105
+ | Use Case | API | Example |
106
+ |----------|-----|---------|
107
+ | Configuration values | Exports | File paths, settings |
108
+ | Environment-specific logic | Define | Different services per env |
109
+ | Side effects | Exports | Database connections, I/O |
110
+ | Conditional processing | Define | Algorithm selection |
123
111
 
124
- ### Thread Safety
112
+ ## Key Features
125
113
 
126
- Taski is thread-safe and handles concurrent access gracefully:
114
+ - **Automatic Dependency Resolution**: Dependencies detected through static analysis
115
+ - **Thread-Safe**: Safe for concurrent access
116
+ - **Circular Dependency Detection**: Clear error messages with detailed paths
117
+ - **Granular Execution**: Build individual tasks or complete graphs
118
+ - **Memory Management**: Built-in reset mechanisms
127
119
 
128
- ```ruby
129
- # Multiple threads can safely access the same task
130
- threads = 5.times.map do
131
- Thread.new { MyTask.some_value }
132
- end
120
+ ### Granular Task Execution
133
121
 
134
- # All threads get the same instance - built only once
135
- results = threads.map(&:value)
136
- ```
122
+ Execute any task individually - Taski builds only required dependencies:
137
123
 
138
- ### Error Handling
124
+ ```ruby
125
+ # Build specific components
126
+ ConfigLoader.build # Builds only ConfigLoader
127
+ # => Config loaded: MyApp v1.0.0
139
128
 
140
- Comprehensive error handling with custom exception types:
129
+ EnvironmentConfig.build # Builds EnvironmentConfig and its dependencies
130
+ # => Using database: localhost:5432
131
+ # => Environment: development
141
132
 
142
- ```ruby
143
- begin
144
- TaskWithCircularDep.build
145
- rescue Taski::CircularDependencyError => e
146
- puts "Circular dependency detected: #{e.message}"
147
- rescue Taski::TaskBuildError => e
148
- puts "Build failed: #{e.message}"
149
- end
133
+ # Access values (triggers build if needed)
134
+ puts ConfigLoader.version # Builds ConfigLoader if not built
135
+ # => 1.0.0
150
136
  ```
151
137
 
152
138
  ### Lifecycle Management
153
139
 
154
- Full control over task lifecycle:
140
+ Tasks can define both build and clean methods. Clean operations run in reverse dependency order:
155
141
 
156
142
  ```ruby
157
- class ProcessingTask < Taski::Task
143
+ class DatabaseSetup < Taski::Task
144
+ exports :connection
145
+
158
146
  def build
159
- # Setup and processing logic
160
- puts "Processing data..."
147
+ @connection = "db-connection"
148
+ puts "Database connected"
161
149
  end
162
150
 
163
151
  def clean
164
- # Cleanup logic (runs in reverse dependency order)
165
- puts "Cleaning up temporary files..."
166
- end
167
- end
168
-
169
- # Build dependencies in correct order
170
- ProcessingTask.build
171
-
172
- # Clean in reverse order
173
- ProcessingTask.clean
174
- ```
175
-
176
- ## 🏗️ Complex Example
177
-
178
- Here's a realistic example showing both APIs working together:
179
-
180
- ```ruby
181
- # Environment configuration using Define API
182
- class Environment < Taski::Task
183
- define :database_url, -> {
184
- case ENV['RAILS_ENV']
185
- when 'production'
186
- ProductionDB.connection_string
187
- when 'test'
188
- TestDB.connection_string
189
- else
190
- "sqlite3://development.db"
191
- end
192
- }
193
-
194
- define :redis_config, -> {
195
- if FeatureFlag.enabled?(:redis_cache)
196
- RedisService.configuration
197
- else
198
- nil
199
- end
200
- }
201
- end
202
-
203
- # Static configuration using Exports API
204
- class AppConfig < Taski::Task
205
- exports :app_name, :version, :port
206
-
207
- def build
208
- @app_name = "MyWebApp"
209
- @version = "2.1.0"
210
- @port = ENV.fetch('PORT', 3000).to_i
152
+ puts "Database disconnected"
211
153
  end
212
154
  end
213
155
 
214
- # Application startup combining both APIs
215
- class Application < Taski::Task
156
+ class WebServer < Taski::Task
216
157
  def build
217
- puts "Starting #{AppConfig.app_name} v#{AppConfig.version}"
218
- puts "Database: #{Environment.database_url}"
219
- puts "Redis: #{Environment.redis_config || 'disabled'}"
220
- puts "Port: #{AppConfig.port}"
221
-
222
- # Start the application...
158
+ puts "Web server started with #{DatabaseSetup.connection}"
223
159
  end
224
160
 
225
161
  def clean
226
- puts "Shutting down #{AppConfig.app_name}..."
227
- # Cleanup logic...
162
+ puts "Web server stopped"
228
163
  end
229
164
  end
230
165
 
231
- # Everything runs in the correct order automatically
232
- Application.build
166
+ WebServer.build
167
+ # => Database connected
168
+ # => Web server started with db-connection
169
+
170
+ WebServer.clean
171
+ # => Web server stopped
172
+ # => Database disconnected
233
173
  ```
234
174
 
235
- ## 📦 Installation
175
+ ### Error Handling
236
176
 
237
- > **⚠️ Warning:** Taski is currently in development. API changes may occur. Use at your own risk in production environments.
177
+ ```ruby
178
+ begin
179
+ TaskWithCircularDep.build
180
+ rescue Taski::CircularDependencyError => e
181
+ puts "Circular dependency: #{e.message}"
182
+ end
183
+ # => Circular dependency: Circular dependency detected!
184
+ # => Cycle: TaskA → TaskB → TaskA
185
+ # =>
186
+ # => The dependency chain is:
187
+ # => 1. TaskA is trying to build → TaskB
188
+ # => 2. TaskB is trying to build → TaskA
189
+ ```
238
190
 
239
- Add this line to your application's Gemfile:
191
+ ## 📦 Installation
240
192
 
241
193
  ```ruby
242
194
  gem 'taski'
243
195
  ```
244
196
 
245
- And then execute:
246
-
247
197
  ```bash
248
198
  bundle install
249
199
  ```
250
200
 
251
- Or install it yourself as:
252
-
253
- ```bash
254
- gem install taski
255
- ```
256
-
257
- For development and testing purposes, you can also install directly from the repository:
258
-
259
- ```ruby
260
- # In your Gemfile
261
- gem 'taski', git: 'https://github.com/[USERNAME]/taski.git'
262
- ```
263
-
264
201
  ## 🧪 Testing
265
202
 
266
- Taski includes comprehensive test coverage. Run the test suite:
267
-
268
203
  ```bash
269
204
  bundle exec rake test
270
205
  ```
271
206
 
272
- > **ℹ️ Note:** Test output may include warnings about method redefinition from the `define` API. These warnings are expected and can be safely ignored.
273
-
274
-
275
207
  ## 🏛️ Architecture
276
208
 
277
- Taski is built with a modular architecture:
278
-
279
- - **Task Base**: Core framework and constants
209
+ - **Task Base**: Core framework
280
210
  - **Exports API**: Static dependency resolution
281
211
  - **Define API**: Dynamic dependency resolution
282
- - **Instance Management**: Thread-safe lifecycle management
283
- - **Dependency Resolver**: Topological sorting and analysis
284
- - **Static Analyzer**: AST-based dependency detection
285
-
286
- ## 🚧 Development Status
287
-
288
- **Taski is currently in active development and should be considered experimental.** While the core functionality is working and well-tested, the API may undergo changes as we refine the framework based on feedback and real-world usage.
289
-
290
- ### Current Development Phase
291
-
292
- - ✅ **Core Framework**: Dependency resolution, both APIs, thread safety
293
- - ✅ **Testing**: Comprehensive test suite with 38+ tests
294
- - ✅ **Type Safety**: RBS definitions and Steep integration
295
- - 🚧 **API Stability**: Some breaking changes may occur
296
- - 🚧 **Performance**: Optimizations for large dependency graphs
297
- - 🚧 **Documentation**: Examples and best practices
298
-
299
- ### Known Limitations
300
-
301
- - **API Changes**: Breaking changes may occur in minor version updates
302
- - **Production Readiness**: Not yet recommended for production environments
303
- - **Static Analysis**: Works best with straightforward Ruby code patterns
304
- - **Metaprogramming**: Complex metaprogramming may require manual dependency specification
305
- - **Performance**: Not yet optimized for very large dependency graphs (1000+ tasks)
306
- - **Method Redefinition Warnings**: Using `define` API may generate Ruby warnings about method redefinition (this is expected behavior)
307
-
308
- ### Future Development
309
-
310
- The future direction of Taski will be determined based on community feedback, real-world usage, and identified needs. Development priorities may include areas such as performance optimization, enhanced static analysis, and improved documentation, but specific roadmap items have not yet been finalized.
311
-
312
- ### Contributing to Development
313
-
314
- We welcome contributions during this development phase! Areas where help is especially appreciated:
315
-
316
- - **Real-world Testing**: Try Taski in your projects and report issues
317
- - **Performance Testing**: Test with large dependency graphs
318
- - **API Feedback**: Suggest improvements to the developer experience
319
- - **Documentation**: Help improve examples and guides
212
+ - **Instance Management**: Thread-safe lifecycle
213
+ - **Dependency Resolver**: Topological sorting
320
214
 
321
215
  ## Contributing
322
216
 
323
- Bug reports and pull requests are welcome on GitHub at https://github.com/ahogappa/taski.
217
+ Bug reports and pull requests welcome at https://github.com/ahogappa/taski.
324
218
 
325
219
  ## License
326
220
 
327
- The gem is available as open source under the [MIT License](LICENSE).
221
+ MIT License
328
222
 
329
223
  ---
330
224
 
331
- **Taski** - Build complex dependency graphs with simple, elegant Ruby code. 🚀
332
-
333
- > **Experimental Software**: Please use responsibly and provide feedback to help us reach v1.0!
225
+ **Taski** - Build dependency graphs with elegant Ruby code. 🚀
data/Rakefile CHANGED
@@ -10,4 +10,10 @@ Rake::TestTask.new(:test) do |t|
10
10
  t.verbose = true
11
11
  end
12
12
 
13
- task default: %i[test]
13
+ begin
14
+ require "standard/rake"
15
+ rescue LoadError
16
+ # Standard not available
17
+ end
18
+
19
+ task default: %i[test standard]
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # Complex example from README showing both APIs
3
3
 
4
- require_relative '../lib/taski'
4
+ require_relative "../lib/taski"
5
5
 
6
6
  # Mock classes for the example
7
7
  class ProductionDB < Taski::Task
@@ -11,7 +11,7 @@ class ProductionDB < Taski::Task
11
11
  end
12
12
  end
13
13
 
14
- class TestDB < Taski::Task
14
+ class TestDB < Taski::Task
15
15
  exports :connection_string
16
16
  def build
17
17
  @connection_string = "postgres://test-server/app_test"
@@ -20,7 +20,7 @@ end
20
20
 
21
21
  module FeatureFlag
22
22
  def self.enabled?(flag)
23
- ENV["FEATURE_#{flag.to_s.upcase}"] == 'true'
23
+ ENV["FEATURE_#{flag.to_s.upcase}"] == "true"
24
24
  end
25
25
  end
26
26
 
@@ -34,11 +34,11 @@ end
34
34
  # Environment configuration using Define API
35
35
  class Environment < Taski::Task
36
36
  define :database_url, -> {
37
- case ENV['RAILS_ENV']
38
- when 'production'
37
+ case ENV["RAILS_ENV"]
38
+ when "production"
39
39
  ProductionDB.connection_string
40
- when 'test'
41
- TestDB.connection_string
40
+ when "test"
41
+ TestDB.connection_string
42
42
  else
43
43
  "sqlite3://development.db"
44
44
  end
@@ -47,8 +47,6 @@ class Environment < Taski::Task
47
47
  define :redis_config, -> {
48
48
  if FeatureFlag.enabled?(:redis_cache)
49
49
  RedisService.configuration
50
- else
51
- nil
52
50
  end
53
51
  }
54
52
 
@@ -57,14 +55,14 @@ class Environment < Taski::Task
57
55
  end
58
56
  end
59
57
 
60
- # Static configuration using Exports API
58
+ # Static configuration using Exports API
61
59
  class AppConfig < Taski::Task
62
60
  exports :app_name, :version, :port
63
61
 
64
62
  def build
65
63
  @app_name = "MyWebApp"
66
64
  @version = "2.1.0"
67
- @port = ENV.fetch('PORT', 3000).to_i
65
+ @port = ENV.fetch("PORT", 3000).to_i
68
66
  end
69
67
  end
70
68
 
@@ -73,7 +71,7 @@ class Application < Taski::Task
73
71
  def build
74
72
  puts "Starting #{AppConfig.app_name} v#{AppConfig.version}"
75
73
  puts "Database: #{Environment.database_url}"
76
- puts "Redis: #{Environment.redis_config || 'disabled'}"
74
+ puts "Redis: #{Environment.redis_config || "disabled"}"
77
75
  puts "Port: #{AppConfig.port}"
78
76
  end
79
77
 
@@ -86,24 +84,24 @@ end
86
84
  puts "=== Complex Example ==="
87
85
 
88
86
  puts "\n1. Development Environment (default):"
89
- ENV.delete('RAILS_ENV')
90
- ENV.delete('FEATURE_REDIS_CACHE')
87
+ ENV.delete("RAILS_ENV")
88
+ ENV.delete("FEATURE_REDIS_CACHE")
91
89
  Application.build
92
90
  Application.reset!
93
91
 
94
92
  puts "\n2. Test Environment:"
95
- ENV['RAILS_ENV'] = 'test'
93
+ ENV["RAILS_ENV"] = "test"
96
94
  # Reset Environment to re-evaluate define blocks
97
95
  Environment.reset!
98
96
  Application.build
99
97
  Application.reset!
100
98
 
101
99
  puts "\n3. Production with Redis:"
102
- ENV['RAILS_ENV'] = 'production'
103
- ENV['FEATURE_REDIS_CACHE'] = 'true'
100
+ ENV["RAILS_ENV"] = "production"
101
+ ENV["FEATURE_REDIS_CACHE"] = "true"
104
102
  # Reset Environment to re-evaluate define blocks
105
103
  Environment.reset!
106
104
  Application.build
107
105
 
108
106
  puts "\n4. Cleanup:"
109
- Application.clean
107
+ Application.clean
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # Quick Start example from README
3
3
 
4
- require_relative '../lib/taski'
4
+ require_relative "../lib/taski"
5
5
 
6
6
  # Simple static dependency using Exports API
7
7
  class DatabaseSetup < Taski::Task
@@ -27,4 +27,4 @@ end
27
27
  puts "=== Quick Start Example ==="
28
28
  APIServer.build
29
29
 
30
- puts "\nResult: APIServer running on port #{APIServer.port}"
30
+ puts "\nResult: APIServer running on port #{APIServer.port}"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'prism'
3
+ require "prism"
4
4
 
5
5
  module Taski
6
6
  module DependencyAnalyzer
@@ -19,13 +19,19 @@ module Taski
19
19
  result = Prism.parse_file(file_path)
20
20
 
21
21
  unless result.success?
22
- warn "Taski: Parse errors in #{file_path}: #{result.errors.map(&:message).join(', ')}"
22
+ Taski.logger.error("Parse errors in source file",
23
+ file: file_path,
24
+ errors: result.errors.map(&:message),
25
+ method: "#{klass}##{method_name}")
23
26
  return []
24
27
  end
25
28
 
26
29
  # Handle warnings if present
27
30
  if result.warnings.any?
28
- warn "Taski: Parse warnings in #{file_path}: #{result.warnings.map(&:message).join(', ')}"
31
+ Taski.logger.warn("Parse warnings in source file",
32
+ file: file_path,
33
+ warnings: result.warnings.map(&:message),
34
+ method: "#{klass}##{method_name}")
29
35
  end
30
36
 
31
37
  dependencies = []
@@ -39,10 +45,17 @@ module Taski
39
45
 
40
46
  dependencies.uniq
41
47
  rescue IOError, SystemCallError => e
42
- warn "Taski: Failed to read file #{file_path}: #{e.message}"
48
+ Taski.logger.error("Failed to read source file",
49
+ file: file_path,
50
+ error: e.message,
51
+ method: "#{klass}##{method_name}")
43
52
  []
44
53
  rescue => e
45
- warn "Taski: Failed to analyze method #{klass}##{method_name}: #{e.message}"
54
+ Taski.logger.error("Failed to analyze method dependencies",
55
+ class: klass.name,
56
+ method: method_name,
57
+ error: e.message,
58
+ error_class: e.class.name)
46
59
  []
47
60
  end
48
61
  end
@@ -151,12 +164,9 @@ module Taski
151
164
  else
152
165
  child_name
153
166
  end
154
- else
155
- nil
156
167
  end
157
168
  end
158
169
  end
159
-
160
170
  end
161
171
  end
162
172
  end
@@ -2,13 +2,13 @@
2
2
 
3
3
  module Taski
4
4
  # Custom exceptions for Taski framework
5
-
5
+
6
6
  # Raised when circular dependencies are detected between tasks
7
7
  class CircularDependencyError < StandardError; end
8
-
8
+
9
9
  # Raised when task analysis fails (e.g., constant resolution errors)
10
10
  class TaskAnalysisError < StandardError; end
11
-
11
+
12
12
  # Raised when task building fails during execution
13
13
  class TaskBuildError < StandardError; end
14
- end
14
+ end