-
Notifications
You must be signed in to change notification settings - Fork 0
/
tool.tcl
93 lines (72 loc) · 2.57 KB
/
tool.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
# -*- tcl -*- Copyright (c) 2012-2024 Andreas Kupries
# # ## ### ##### ######## ############# #####################
## Manage tool requirements
# # ## ### ##### ######## ############# #####################
## Export (internals)
namespace eval ::kettle::tool {
namespace export {[a-z]*}
namespace ensemble create
namespace import ::kettle::io
namespace import ::kettle::option
namespace import ::kettle::status
# Dictionary. Error information for tools which were not found.
variable err {}
}
# # ## ### ##### ######## ############# #####################
## API.
proc ::kettle::tool::declare {names {validator {}}} {
variable err
set primary [lindex $names 0]
dict set err primary {}
option define --with-$primary [subst {
Path to the tool '$primary'.
Overides kettle's search on the PATH.
}] {} readable.file
option no-work-key --with-$primary
set sep [expr {$::tcl_platform(platform) eq "windows" ? ";" : ":"}]
foreach p [split $::env(PATH) $sep] {
dict lappend err $primary "Searching $p"
}
foreach name $names {
# TODO : Use our own search command here, switch to the next name only
# if the list of paths is exhausted. Right now a validation failure
# immediately switches to the next name, cutton of possible instances of
# the failing name in not-yet-searched paths of the list.
set cmd [auto_execok $name]
# NOTE: We unbox the list to get at the actual command path to store as
# option default.
##
# ATTENTION: A multi-element list is only possible for the small list of
# Windows shell builtins hardwired into auto_execok. None of them are
# used as tools here in kettle.
option set-default --with-$primary [lindex $cmd 0]
# Do not try to validate applications which were not found.
# Continue search.
if {![llength $cmd]} continue
# Do not try to validate if we have no validation code.
# Assume ok, stop search.
if {$validator eq ""} break
# Validate. If ok, stop search.
set msg {}
if {[apply [list {cmd msgvar} $validator] $cmd msg]} break
dict lappend err $primary "Rejected: $cmd ($msg)"
# Validation failed, revert, continue search.
option set-default --with-$primary {}
}
return
}
proc ::kettle::tool::get {name} {
set cmd [option get --with-$name]
if {![llength $cmd]} {
variable err
io err {
io puts "Tool $name required, but not found in PATH"
io puts "Please specify its location through option --with-$name"
io puts \n[join [dict get $err $name] \n]
}
status fail
}
return $cmd
}
# # ## ### ##### ######## ############# #####################
return