taski 0.1.0 → 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.
data/lib/taski.rb CHANGED
@@ -1,155 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "taski/version"
4
-
5
- module Taski
6
- class Reference
7
- def initialize(klass)
8
- @klass = klass
9
- end
10
-
11
- def deref
12
- Object.const_get(@klass)
13
- end
14
-
15
- def inspect
16
- "&#{@klass}"
17
- end
18
- end
19
-
20
- class Task
21
- def self.__resolve__
22
- @__resolve__ ||= {}
23
- end
24
-
25
- def self.ref(klass)
26
- ref = Reference.new(klass)
27
- throw :unresolve, ref
28
- end
29
-
30
- def self.definition(name, block, **options)
31
- @dependencies ||= []
32
- @definitions ||= {}
33
-
34
- self.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
35
- def self.#{name}
36
- __resolve__[__callee__] ||= false
37
- if __resolve__[__callee__]
38
- # already resolved
39
- else
40
- __resolve__[__callee__] = true
41
- throw :unresolve, [self, __callee__]
42
- end
43
- end
44
- RUBY
45
-
46
- classes = []
47
- loop do
48
- klass, task = catch(:unresolve) do
49
- block.call
50
- nil
51
- end
52
-
53
- if klass.nil?
54
- classes.each do |task_class|
55
- task_class[:klass].class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
56
- __resolve__ = {}
57
- RUBY
58
- end
59
-
60
- break
61
- else
62
- classes << { klass:, task: }
63
- end
64
- end
65
-
66
- @dependencies += classes
67
- @definitions[name] = {block:, options:, classes:}
68
- end
69
-
70
- def self.build
71
- resolve_dependences.reverse.each do |task_class|
72
- task_class.new.build
73
- end
74
- end
3
+ require 'set'
4
+ require 'monitor'
75
5
 
76
- def self.clean
77
- resolve_dependences.each do |task_class|
78
- task_class.new.clean
79
- end
80
- end
81
-
82
- def exec_command(command, info = nil, ret = false)
83
- puts "exec: #{info}" if info
84
- puts command
85
-
86
- if ret
87
- ret = `#{command}`.chomp
88
- if $?.exited?
89
- ret
90
- else
91
- raise "Failed to execute command: #{command}"
92
- end
93
- else
94
- system command, exception: true
95
- end
96
- end
97
-
98
- def self.refresh
99
- # TODO
100
- end
101
-
102
- private
103
-
104
- def self.resolve(queue, resolved)
105
- @dependencies.each do |task|
106
- if task[:klass].is_a?(Reference)
107
- task_class = task[:klass].deref
108
- end
109
-
110
- # increase priority
111
- if resolved.include?(task[:klass])
112
- resolved.delete(task[:klass])
113
- end
114
- queue << task[:klass]
115
- end
116
-
117
- # override
118
- self.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
119
- def self.ref(klass)
120
- Object.const_get(klass)
121
- end
122
- RUBY
123
-
124
- @definitions.each do |name, (block, options)|
125
- # override
126
- self.class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
127
- def self.#{name}
128
- @__#{name} ||= @definitions[:#{name}][:block].call
129
- end
130
- RUBY
131
-
132
- self.define_method(name) do
133
- unless instance_variable_defined?("@__#{name}")
134
- instance_variable_set("@__#{name}", self.class.send(name))
135
- end
136
- instance_variable_get("@__#{name}")
137
- end
138
- end
139
-
140
- self
141
- end
142
-
143
- def self.resolve_dependences
144
- queue = [self]
145
- resolved = []
6
+ # Load core components
7
+ require_relative "taski/version"
8
+ require_relative "taski/exceptions"
9
+ require_relative "taski/reference"
10
+ require_relative "taski/dependency_analyzer"
146
11
 
147
- while queue.any?
148
- resolved << task_class = queue.shift
149
- task_class.resolve(queue, resolved)
150
- end
12
+ # Load Task class components
13
+ require_relative "taski/task/base"
14
+ require_relative "taski/task/exports_api"
15
+ require_relative "taski/task/define_api"
16
+ require_relative "taski/task/instance_management"
17
+ require_relative "taski/task/dependency_resolver"
151
18
 
152
- resolved
153
- end
154
- end
155
- end
19
+ module Taski
20
+ # Main module for the Taski task framework
21
+ #
22
+ # Taski provides a framework for defining and managing task dependencies
23
+ # with two complementary APIs:
24
+ # 1. Exports API - Export instance variables as class methods (static dependencies)
25
+ # 2. Define API - Define lazy-evaluated values with dynamic dependency resolution
26
+ #
27
+ # Use Define API when:
28
+ # - Dependencies change based on runtime conditions
29
+ # - Environment-specific configurations
30
+ # - Feature flags determine which classes to use
31
+ # - Complex conditional logic determines dependencies
32
+ #
33
+ # Features:
34
+ # - Automatic dependency resolution (static and dynamic)
35
+ # - Static analysis of method dependencies
36
+ # - Runtime dependency resolution for conditional logic
37
+ # - Thread-safe task building
38
+ # - Circular dependency detection
39
+ # - Memory leak prevention
40
+ end
data/sig/taski.rbs CHANGED
@@ -1,4 +1,62 @@
1
1
  module Taski
2
2
  VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end
3
+
4
+ # Custom exceptions
5
+ class CircularDependencyError < StandardError
6
+ end
7
+
8
+ class TaskAnalysisError < StandardError
9
+ end
10
+
11
+ class TaskBuildError < StandardError
12
+ end
13
+
14
+ # Reference class for task references
15
+ class Reference
16
+ @klass: String
17
+
18
+ def initialize: (String klass) -> void
19
+ def deref: () -> Class
20
+ def ==: (untyped other) -> bool
21
+ def inspect: () -> String
22
+ end
23
+
24
+ # Main Task class
25
+ class Task
26
+ # Constants
27
+ THREAD_KEY_SUFFIX: String
28
+ TASKI_ANALYZING_DEFINE_KEY: Symbol
29
+ ANALYZED_METHODS: Array[Symbol]
30
+
31
+ # Hook methods
32
+ def self.method_added: (Symbol method_name) -> void
33
+
34
+ # Public API methods
35
+ def self.exports: (*Symbol names) -> void
36
+ def self.define: (Symbol name, Proc block, **untyped options) -> void
37
+ def self.build: () -> void
38
+ def self.clean: () -> void
39
+ def self.reset!: () -> self
40
+ def self.refresh: () -> self
41
+ def self.resolve: (Array[untyped] queue, Array[untyped] resolved) -> self
42
+ def self.ref: (String klass) -> Reference
43
+ def self.ensure_instance_built: () -> Task
44
+
45
+ # Instance methods
46
+ def build: () -> void
47
+ def clean: () -> void
48
+
49
+ # Allow dynamic method definitions
50
+ def method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
51
+ def respond_to_missing?: (Symbol name, bool include_private) -> bool
52
+
53
+ # Allow dynamic class method definitions
54
+ def self.method_missing: (Symbol name, *untyped args) ?{ (*untyped) -> untyped } -> untyped
55
+ def self.respond_to_missing?: (Symbol name, bool include_private) -> bool
56
+ end
57
+
58
+ # Dependency analyzer module
59
+ module DependencyAnalyzer
60
+ def self.analyze_method: (Class klass, Symbol method_name) -> Array[Class]
61
+ end
62
+ end
metadata CHANGED
@@ -1,14 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taski
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ahogappa
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
- dependencies: []
10
+ date: 2025-06-15 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: prism
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.4'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.4'
12
26
  description: Taski is a Ruby-based task runner currently under development. It allows
13
27
  you to define small, composable tasks along with the outputs they depend on. Taski
14
28
  statically resolves dependencies and executes tasks in the correct topological order,
@@ -21,9 +35,21 @@ executables: []
21
35
  extensions: []
22
36
  extra_rdoc_files: []
23
37
  files:
38
+ - LICENSE
24
39
  - README.md
25
40
  - Rakefile
41
+ - Steepfile
42
+ - examples/complex_example.rb
43
+ - examples/readme_example.rb
26
44
  - lib/taski.rb
45
+ - lib/taski/dependency_analyzer.rb
46
+ - lib/taski/exceptions.rb
47
+ - lib/taski/reference.rb
48
+ - lib/taski/task/base.rb
49
+ - lib/taski/task/define_api.rb
50
+ - lib/taski/task/dependency_resolver.rb
51
+ - lib/taski/task/exports_api.rb
52
+ - lib/taski/task/instance_management.rb
27
53
  - lib/taski/version.rb
28
54
  - sig/taski.rbs
29
55
  homepage: https://github.com/ahogappa/taski
@@ -46,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
46
72
  - !ruby/object:Gem::Version
47
73
  version: '0'
48
74
  requirements: []
49
- rubygems_version: 3.6.7
75
+ rubygems_version: 3.6.2
50
76
  specification_version: 4
51
77
  summary: A simple yet powerful Ruby task runner with static dependency resolution
52
78
  (in development).