-
Notifications
You must be signed in to change notification settings - Fork 0
/
status.tcl
167 lines (125 loc) · 4.06 KB
/
status.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# -*- tcl -*- Copyright (c) 2012-2024 Andreas Kupries
# # ## ### ##### ######## ############# #####################
## General goal status handling
# # ## ### ##### ######## ############# #####################
## Export (internals - recipe definitions, other utilities)
namespace eval ::kettle::status {
namespace export {[a-z]*}
namespace ensemble create
namespace import ::kettle::io
}
# # ## ### ##### ######## ############# #####################
## State
namespace eval ::kettle::status {
# Stack of currently executing goals.
variable current {}
# Dictionary holding the status of all goals executed.
variable work {}
}
# # ## ### ##### ######## ############# #####################
## API.
##
## Note: The database keys contain the source-dir (normalized absolute
## path) to make the data shareable across multiple kettle instances
## calling on each other. This, the location in the key, makes the
## goals properly distinguishable.
proc ::kettle::status::begin {goal} {
variable current
variable work
set key [list [kettle path sourcedir] $goal [kettle option config]]
if {[dict exists $work $key]} {
set status [dict get $work $key]
# ok/fail for the goal -> do not run it again.
if {$status ne "@work"} {
io trace {RUN ($goal) ... DONE ALREADY, STOP}
return -code return
}
# goal still at work -> found a cycle of goals calling
# themselves recursively.
return -code error -errorcode {KETTLE STATUS CYCLE} \
"Cycle in goal definitions: $goal"
# TODO: Determine full set of goals @work.
}
# goal has not run yet. Mark for work, reset overall state, and
# save work database back to the configuration.
dict set work $key state @work
dict set work $key msg {}
lappend current $goal
return
}
proc ::kettle::status::ok {} {
variable current
variable work
io trace {status ok :[lindex $current end]}
set key [list [kettle path sourcedir] [lindex $current end] [kettle option config]]
set current [lreplace $current end end]
#io trace {.... [lindex $key 0]}
#io trace {.... [lindex $key 1]}
#io trace {.... [lindex $key 2]}
dict set work $key state ok
dict set work $key msg OK
Show $key
return -errorcode {KETTLE STATUS OK} -code error ""
}
proc ::kettle::status::fail {{msg FAIL}} {
variable current
variable work
io trace {status fail :[lindex $current end] $msg}
set key [list [kettle path sourcedir] [lindex $current end] [kettle option config]]
set current [lreplace $current end end]
dict set work $key state fail
dict set work $key msg $msg
Show $key
return -errorcode {KETTLE STATUS FAIL} -code error ""
}
proc ::kettle::status::is {goal {src {}} args} {
variable work
# possible results: unknown|ok|fail|work
#io trace {status is :$goal ($args)}
#io trace { @$src}
#io trace { %$args}
if {$src eq {}} { set src [kettle path sourcedir] }
set key [list $src $goal [kettle option config {*}$args]]
#io trace {.... [lindex $key 0]}
#io trace {.... [lindex $key 1]}
#io trace {.... [lindex $key 2]}
if {![dict exists $work $key state]} {
return unknown
}
return [dict get $work $key state]
}
proc ::kettle::status::save {{path {}}} {
variable work
if {$path eq {}} {
set path [kettle path tmpfile state_]
kettle path ensure-cleanup $path
}
kettle path write $path $work
io trace {status saved to $path}
return $path
}
proc ::kettle::status::load {file} {
io trace {status loaded from $file}
variable work [kettle path cat $file]
return
}
proc ::kettle::status::clear {} {
variable work {}
return
}
# # ## ### ##### ######## ############# #####################
proc ::kettle::status::Show {key} {
variable work
set state [dict get $work $key state]
set msg [dict get $work $key msg]
if {$state ne "ok"} {
io $state { io puts $msg }
} else {
io for-gui {
io $state { io puts $msg }
}
}
return
}
# # ## ### ##### ######## ############# #####################
return