Ticket #5063: port.tcl.diff2

File port.tcl.diff2, 14.9 KB (added by erickt@…, 19 years ago)

update to add dependent port checking when uninstalling

Line 
1Index: port.tcl
2===================================================================
3RCS file: /Volumes/src/cvs/od/proj/darwinports/base/src/port/port.tcl,v
4retrieving revision 1.106
5diff -r1.106 port.tcl
6123c123
7<       set usage { [-vdqfonasbckt] [-D portdir] [-u porturl] action [actionflags]
8---
9>       set usage { [-vdqfonasbcktyAR] [-D portdir] [-u porturl] action [actionflags]
10129c129
11<       contents, deps, variants, search, list, echo, sync,
12---
13>       contents, deps, dependents, variants, search, list, echo, sync,
14262a263
15>
16348a350,393
17> # Execute the enclosed block once for every element in the portnamelist
18> # When the block is entered, the variables portname, portversion, options, and variations
19> # will have been set
20> proc foreachportname {portnamelist block} {
21>       foreach portname $portnamelist {
22>               set result [portname_to_portspec $portname]
23>
24>               array set port [lindex $result 1]
25>
26>               # XXX: hack?
27>               # these two options aren't typically defined
28>               if {![info exists port(url)]} {
29>                       set port(url) []
30>               }
31>
32>               if {![info exists port(options)]} {
33>                       set port(options) []
34>               }
35>
36>               # hack to get around variants that only have one item in them
37>               set variants []
38>
39>               if {[info exists port(variants)]} {
40>                       foreach variant $port(variants) {
41>                               set variants [concat $variant "+"]
42>                       }
43>               }
44>
45>               set port(variants) $variants
46>
47>               uplevel 1 "
48>                       set porturl \"$port(url)\"
49>                       set portname \"$port(name)\"
50>                       set portversion \"$port(version)\"
51>                       array unset variations
52>                       array set variations { $port(variants) }
53>                       array unset options
54>                       array set options { $port(options) }
55>                       $block
56>                       "
57>       }
58> }
59>
60>
61370,371c415,418
62< proc get_matching_ports {pattern {casesensitive no} {matchstyle glob} {field name}} {
63<       if {[catch {set res [dportsearch $pattern $casesensitive $matchstyle $field]} result]} {
64---
65>
66> # factored out this common function call to turn a portname into a portspec
67> proc portname_to_portspec {portname {case_sensitive no} {matchstyle exact} {field name}} {
68>       if {[catch {set res [dportsearch $portname $case_sensitive $matchstyle $field]} result]} {
69374c421
70<               fatal "search for portname $pattern failed: $result"
71---
72>               fatal "search for portname $portname failed: $result"
73376a424,429
74>       return $res
75> }
76>
77>
78> proc get_matching_ports {pattern {case_sensitive no} {matchstyle glob} {field name}} {
79>       set res [portname_to_portspec $pattern $case_sensitive $matchstyle $field]
80499,503c552,553
81<                       if {[catch {set res [dportsearch $portname no exact]} result]} {
82<                               global errorInfo
83<                               ui_debug "$errorInfo"
84<                               fatal "search for portname $portname failed: $result"
85<                       }
86---
87>                       set res [portname_to_portspec $portname]
88>
89540a591,699
90> # look up all the packages each portname in the portlist depends on
91> proc get_dependencies { portlist {case_sensitive no} } {
92>       set depstypes {depends_build depends_lib depends_run}
93>       set depstypes_descr {"build" "library" "runtime"}
94>
95>       set lookup [list]
96>
97>       foreachport $portlist {
98>               # Get info about the port
99>               set result [portname_to_portspec $portname $case_sensitive]
100>
101>               if {$result == ""} {
102>                       fatal "No port $portname found."
103>               }
104>
105>               array set portinfo [lindex $result 1]
106>               set depends [list]
107>
108>               # look up the dependencies
109>               foreach depstype $depstypes depsdecr $depstypes_descr {
110>                       set deps [list]
111>                       if {[info exists portinfo($depstype)] && $portinfo($depstype) != ""} {
112>                               foreach i $portinfo($depstype) {
113>                                       lappend deps [lindex [split [lindex $i 0] :] end]
114>                               }
115>                       }
116>
117>                       if {[llength $deps] != 0} {
118>                               lappend depends $depsdecr
119>                               lappend depends [lsort -unique $deps]
120>                       }
121>               }
122>
123>               lappend lookup $portname
124>               lappend lookup $depends
125>       }
126>
127>       return $lookup
128> }
129>
130>
131> # look up the dependent packages for each portname in the portlist
132> proc get_all_dependents {} {
133>       if {[ui_isset ports_verbose]} {
134>               puts "getting all dependencies"
135>       }
136>       
137>       set all_dependencies [get_dependencies [get_installed_ports]]
138>
139>       if {[ui_isset ports_verbose]} {
140>               puts "getting all dependencies -- finished"
141>       }
142>
143>       array set dependents [list]
144>       
145>       if {[ui_isset ports_verbose]} {
146>               puts "getting dependent tasks"
147>       }
148>
149>       # find the dependent packages
150>       foreach {portname depsdecr_dependencies} $all_dependencies {
151>               foreach {depsdecr dependencies} $depsdecr_dependencies {
152>                       foreach dep $dependencies {
153>                               if {[info exists dependents($dep)]} {
154>                                       set dependents($dep) [concat $portname $dependents($dep)]
155>                               } else {
156>                                       set dependents($dep) [list $portname]
157>                               }
158>                       }
159>               }
160>       }
161>
162>       if {[ui_isset ports_verbose]} {
163>               puts "getting dependent tasks -- finished"
164>       }
165>
166>       return [array get dependents]
167> }
168>
169>
170> proc get_dependents { portlist {find_all no} } {
171>       # if no ports are specified just return null
172>       if {[llength portlist] == 0} {
173>               return
174>       }
175>
176>       array set all_dependents [get_all_dependents]
177>       set result [list]
178>
179>       foreachport $portlist {
180>               set dependents $all_dependents($portname)
181>
182>               # grab all the dependent packages our dependent package depends on
183>               if {$find_all == "yes"} {
184>                       foreach dep $dependents {
185>                               if {[info exists all_dependents($dep)]} {
186>                                       foreach d $all_dependents($dep) {
187>                                               lappend dependents $d
188>                                       }
189>                               }
190>                       }
191>               }
192>               
193>               # make sure that there are no repeating dependents
194>               lappend result $portname [lsort -unique $dependents]
195>       }
196>
197>       return $result
198> }
199544a704
200>
201549a710
202>
2031008,1009d1168
204<
205<
2061029,1031c1188,1191
207<                               d { set ui_options(ports_debug) yes
208<                                       # debug implies verbose
209<                                       set ui_options(ports_verbose) yes
210---
211>                               d {
212>                                               set ui_options(ports_debug) yes
213>                                               # debug implies verbose
214>                                               set ui_options(ports_verbose) yes
2151033,1035c1193,1196
216<                               q { set ui_options(ports_quiet) yes
217<                                       set ui_options(ports_verbose) no
218<                                       set ui_options(ports_debug) no
219---
220>                               q {
221>                                               set ui_options(ports_quiet) yes
222>                                               set ui_options(ports_verbose) no
223>                                               set ui_options(ports_debug) no
2241037,1046c1198,1210
225<                               f { set global_options(ports_force) yes                 }
226<                               o { set global_options(ports_ignore_older) yes  }
227<                               n { set global_options(ports_nodeps) yes                }
228<                               a { set global_options(port_upgrade_all) yes    }
229<                               u { set global_options(port_uninstall_old) yes  }
230<                               s { set global_options(ports_source_only) yes   }
231<                               b { set global_options(ports_binary_only) yes   }
232<                               c { set global_options(ports_autoclean) yes             }
233<                               k { set global_options(ports_autoclean) no              }
234<                               t { set global_options(ports_trace) yes                 }
235---
236>                               f { set global_options(ports_force) yes }
237>                               o { set global_options(ports_ignore_older) yes }
238>                               n { set global_options(ports_nodeps) yes }
239>                               a { set global_options(port_upgrade_all) yes }
240>                               R { set global_options(port_upgrade_rebuild_dependents) yes }
241>                               A { set global_options(port_dependents_show_all) yes }
242>                               u { set global_options(port_uninstall_old) yes }
243>                               y { set global_options(port_yes) yes }
244>                               s { set global_options(ports_source_only) yes }
245>                               b { set global_options(ports_binary_only) yes }
246>                               c { set global_options(ports_autoclean) yes }
247>                               k { set global_options(ports_autoclean) no }
248>                               t { set global_options(ports_trace) yes }
2491118,1122c1282
250<                       if {[catch {dportsearch $portname no exact} result]} {
251<                               global errorInfo
252<                               ui_debug "$errorInfo"
253<                               fatal "search for portname $portname failed: $result"
254<                       }
255---
256>                       set result [portname_to_portspec $portname]
2571282c1442,1447
258<                 
259---
260>
261>               if {[info exists global_options(port_upgrade_rebuild_dependents)] } {
262>                       # grab all the dependents and their dependents recursively
263>                       array set all_dependents [get_dependents $portlist yes]
264>               }
265>         
2661291a1457,1463
267>
268>                       if {[info exists global_options(port_upgrade_rebuild_dependents)] } {
269>                               set dependents $all_dependents($portname)
270>                               foreach i [lsort $dependents] {
271>                                       darwinports::upgrade $portname "port:$i"
272>                               }
273>                       }
2741321a1494,1538
275>               # note we don't want to uninstall dependent tasks of deactivated projects
276>
277>               if {[info exists global_options(no_deps)]} {
278>                       set remove_deps no
279>               } else {
280>                       set remove_deps yes
281>               }
282>
283>               ####
284>               
285>               proc find_uninstallable {portlist remove_deps} {
286>                       # grab the dependent ports for all of the ports we're uninstalling
287>                       # how should this work with respect to deactivated projects?
288>                       if {[info exists global_options(nodeps)]} {
289>                               array set dependents [list]
290>                       } else {
291>                               array set dependents [get_dependents $portlist yes]
292>                       }
293>
294>                       set list_ports []
295>                       set list_depends []
296>
297>                       foreachport $portlist {
298>                               set original_portname $portname
299>                               set original_version [composite_version $portversion [array get variations]]
300>                               set original_options [array get options]
301>
302>                               if {[info exists dependents($portname)]} {
303>                                       foreachportname $dependents($portname) {
304>                                               set port_version [composite_version $portversion [array get variations]]
305>                                               set port_options [array get options]
306>
307>                                               lappend list_depends [list $portname $port_version $port_options]
308>                                       }
309>                               }
310>
311>                               lappend list_ports [list $original_portname $original_version $original_options]
312>                       }
313>
314>                       return [list $list_ports $list_depends]
315>               }
316>
317>               set ports []
318>               set depends []
319>
3201325c1542,1549
321<                       set portlist [opUnion $portlist [get_inactive_ports]]
322---
323>
324>                       set pd [find_uninstallable $portlist $remove_deps]
325>                       set ports [concat $ports [lindex $pd 0]]
326>                       set depends [concat $depends [lindex $pd 1]]
327>
328>                       set pd [find_uninstallable [get_installed_ports] no]]
329>                       set ports [concat $ports [lindex $pd 0]]
330>                       set depends [concat $depends [lindex $pd 1]]
3311328a1553,1557
332>
333>                       set pd [find_uninstallable $portlist $remove_deps]
334>
335>                       set ports [concat $ports [lindex $pd 0]]
336>                       set depends [concat $depends [lindex $pd 1]]
3371331,1335c1560,1606
338<               foreachport $portlist {
339<                       if { [catch {portuninstall::uninstall $portname [composite_version $portversion [array get variations]] [array get options]} result] } {
340<                               global errorInfo
341<                               ui_debug "$errorInfo"
342<                               fatal "port uninstall failed: $result"
343---
344>               set ports [lsort -unique $ports]
345>               set depends [lsort -unique $depends]
346>
347>               # print out which ports we're to uninstall
348>               # don't print if we're being quiet
349>               if {![ui_isset ports_quiet]} {
350>                       puts "the following ports will be uninstalled:"
351>                       foreach foo $ports {
352>                               foreach {portname version options} $foo {
353>                                       if {$version != ""} {set version "($version)"}
354>                                       puts "    $portname $version $options"
355>                               }
356>                       }
357>
358>                       puts "\nthese following ports will also be uninstalled:"
359>                       foreach foo $depends {
360>                               foreach {portname version options} $foo {
361>                                       if {$version != ""} {set version "($version)"}
362>                                       puts "    $portname $version $options"
363>                               }
364>                       }
365>               }
366>
367>               # check to make sure we wish to uninstall
368>               if {![info exists global_options(port_yes)]} {
369>                       while {1} {
370>                               puts -nonewline "are you sure you want to uninstall? \[yes/no\]: "
371>                               flush stdout
372>                               gets stdin input
373>
374>                               if {$input == "yes"} {
375>                                       break
376>                               } elseif {$input == "no"} {
377>                                       exit
378>                               }
379>                       }
380>               }
381>
382>               foreach foo [concat $ports $depends] {
383>                       foreach {portname version options} $foo {
384>                               puts "uninstall: $portname ($version) $options"
385>
386>                               #if { [catch {portuninstall::uninstall $portname $version $options} result] } {
387>                               #       global errorInfo
388>                               #       ui_debug "$errorInfo"
389>                               #       fatal "port uninstall failed: $result"
390>                               #}
3911427,1431c1698,1699
392<                               if {[catch {set res [dportsearch $portname no exact]} result]} {
393<                                       global errorInfo
394<                                       ui_debug "$errorInfo"
395<                                       fatal "search for portname $portname failed: $result"
396<                               }
397---
398>                               set res [portname_to_portspec $portname]
399>
4001500c1768
401<       
402---
403>
4041502a1771,1776
405>
406>               # grab all the dependencies
407>               array set all_dependencies [get_dependencies $portlist]
408>
409>               # now print them out. note that we want to print in the order
410>               # specified on the command line
4111504,1523c1778,1783
412<                       # Get info about the port
413<                       if {[catch {dportsearch $portname no exact} result]} {
414<                               global errorInfo
415<                               ui_debug "$errorInfo"
416<                               fatal "search for portname $portname failed: $result"
417<                       }
418<       
419<                       if {$result == ""} {
420<                               fatal "No port $portname found."
421<                       }
422<       
423<                       array set portinfo [lindex $result 1]
424<       
425<                       set depstypes {depends_build depends_lib depends_run}
426<                       set depstypes_descr {"build" "library" "runtime"}
427<       
428<                       set nodeps true
429<                       foreach depstype $depstypes depsdecr $depstypes_descr {
430<                               if {[info exists portinfo($depstype)] &&
431<                                       $portinfo($depstype) != ""} {
432---
433>                       array set dependencies $all_dependencies($portname)
434>
435>                       if {[array size dependencies] == 0} {
436>                               puts "$portname has no dependencies"
437>                       } else {
438>                               foreach depsdecr [lsort [array names dependencies]] {
4391525,1526c1785,1786
440<                                       foreach i $portinfo($depstype) {
441<                                               puts "\t[lindex [split [lindex $i 0] :] end]"
442---
443>                                       foreach i $dependencies($depsdecr) {
444>                                               puts "\t$i"
4451528d1787
446<                                       set nodeps false
4471530a1790,1808
448>               }
449>       }
450>
451>       dependents {
452>               global global_options
453>
454>               require_portlist
455>
456>               # grab all the dependents
457>         if {[info exists global_options(port_dependents_show_all)] } {
458>                       array set all_dependents [get_dependents $portlist yes]
459>               } else {
460>                       array set all_dependents [get_dependents $portlist]
461>               }
462>
463>               # now print them out. note that we want to print in the order
464>               # specified on the command line
465>               foreachport $portlist {
466>                       set dependents $all_dependents($portname)
4671532,1534c1810,1816
468<                       # no dependencies found
469<                       if {$nodeps == "true"} {
470<                               puts "$portname has no dependencies"
471---
472>                       if {[llength $dependents] == 0} {
473>                               puts "no packages depend on $portname"
474>                       } else {
475>                               puts "the following packages depend on $portname:"
476>                               foreach i [lsort $dependents] {
477>                                               puts "\t$i"
478>                               }
4791538c1820
480<       
481---
482>
4831543,1547c1825
484<                       if {[catch {dportsearch $portname no exact} result]} {
485<                               global errorInfo
486<                               ui_debug "$errorInfo"
487<                               fatal "search for portname $portname failed: $result"
488<                       }
489---
490>                       set result [portname_to_portspec $portname]
4911574,1578c1852,1853
492<                       if {[catch {set res [dportsearch $portname no]} result]} {
493<                               global errorInfo
494<                               ui_debug "$errorInfo"
495<                               fatal "search for portname $portname failed: $result"
496<                       }
497---
498>                       set res [portname_to_portspec $portname no regexp]
499>
5001622,1627d1896
501<                       
502<                       if {[catch {set res [dportsearch ^$search_string\$ no]} result]} {
503<                               global errorInfo
504<                               ui_debug "$errorInfo"
505<                               fatal "search for portname $search_string failed: $result"
506<                       }
5071628a1898,1899
508>                       set res [portname_to_portspec ^$search_string\$ no regexp]
509>               
5101669,1673c1940,1941
511<                               if {[catch {set res [dportsearch $portname no exact]} result]} {
512<                                       global errorInfo
513<                                       ui_debug "$errorInfo"
514<                                       fatal "search for portname $portname failed: $result"
515<                               }
516---
517>                               set res [portname_to_portspec $portname no exact]
518>