port diagnose fixes

* Allow user config file to not exist, and simply use internal defaults
in that case, rather than creating the file and writing defaults to it.
Defaults may change in the future and the old defaults in the file
would override them.
* Keep config in macports_conf_path with the other config files
* Fail gracefully when there is no Xcode version info for the current
OS version
* Raise an error when the Xcode version info file doesn't exist,
instead of exiting immediately
* Run compilation test in the proper temp dir instead of just whatever
the working directory happens to be
* Use cc in compilation test instead of clang (not all systems have it)
* Use registry2 API to get installed ports and their files
* Don't require root privileges
* Correct information and use more usual terminology in some messages
* Fix typos
This commit is contained in:
Joshua Root
2016-12-27 16:25:07 +11:00
parent 3e4dfa81dd
commit acd931c3c9
2 changed files with 79 additions and 97 deletions
+79 -94
View File
@@ -53,7 +53,7 @@
# Check for archives from all ports exists
# Check for things in /usr/local
# Check for x11.app if the OS is 10.6 and suggest installing xorg-server or the xquartz site
# Add error catching for line's without an equals sign.
# Add error catching for lines without an equals sign.
# Support comments for the parser
# Check for amount of drive space
# Move port_diagnose.ini to the port tree, below _resources
@@ -90,20 +90,27 @@ namespace eval diagnose {
}
array set config_options [list]
set parser_options {"macports_location" "profile_path" "shell_location" "xcode_version_10.10" "xcode_version_10.9" "xcode_version_10.8" \
"xcode_version_10.7" "xcode_version_10.6" "xcode_version_10.7" "xcode_version_10.6" "xcode_version_10.5" \
"xcode_version_10.4" "xcode_build"}
set parser_options [list macports_location profile_path shell_location \
xcode_version_${macports::macosx_version} xcode_build]
set user_config_path ${macports::portdbpath}/port_diagnose.ini
set user_config_path "${macports::autoconf::macports_conf_path}/port_diagnose.ini"
set xcode_config_path [macports::getdefaultportresourcepath "macports1.0/xcode_versions.ini"]
# Make sure at least a default copy of the xcode and user config exist
make_xcode_config $xcode_config_path
make_user_config $user_config_path
# Make sure the xcode config exists
check_xcode_config $xcode_config_path
# Read the config files
get_config config_options $parser_options $user_config_path
get_config config_options $parser_options $xcode_config_path
if {![info exists config_options(macports_location)]} {
set config_options(macports_location) "${macports::prefix}"
}
if {![info exists config_options(profile_path)]} {
set config_options(profile_path) "${macports::user_home}/.bash_profile"
}
if {![info exists config_options(shell_location)]} {
set config_options(shell_location) /bin/bash
}
# Start the checks
check_path $config_options(macports_location) $config_options(profile_path) $config_options(shell_location)
@@ -159,7 +166,7 @@ namespace eval diagnose {
if {$xcode_select eq ""} {
ui_warn "Xcode Command Line Tools are not installed! To install them, please enter the command:
xcode-selct --install"
xcode-select --install"
success_fail 0
return
}
@@ -202,7 +209,7 @@ namespace eval diagnose {
# Returns:
# None
if {${diagnose::quiet} == 0} {
if {!${diagnose::quiet}} {
ui_msg -nonewline "Checking for $string... "
}
}
@@ -216,7 +223,7 @@ namespace eval diagnose {
# Returns:
# None
if {${diagnose::quiet} eq 0} {
if {!${diagnose::quiet}} {
if {$result == 1} {
@@ -241,20 +248,25 @@ namespace eval diagnose {
output "compilation errors"
set filename "test.c"
set fd [open $filename w]
# 'clang' will fail when using
# https://trac.macports.org/wiki/UsingTheRightCompiler#testing
if {![file isfile /usr/bin/cc]} {
ui_error "No compiler found at /usr/bin/cc"
success_fail 0
return
}
set builddir "[macports::gettmpdir]/port_diagnose"
file mkdir $builddir
set filepath "${builddir}/test.c"
set fd [open $filepath w]
puts $fd "int main() { return 0; }"
close $fd
# 'clang' will fail when using
# https://trac.macports.org/wiki/UsingTheRightCompiler#testing
# TODO: use default C compiler
# TODO: skip if no C compiler installed
catch {exec /usr/bin/clang $filename -o main_test} output
catch {exec /usr/bin/cc $filepath -o "${builddir}/main_test"} output
file delete $filename
file delete "main_test"
file delete -force $builddir
if {[string length $output] > 0} {
# Some type of error
@@ -321,7 +333,7 @@ namespace eval diagnose {
output "Fink"
if {[file exists "/sw"]} {
ui_warn "it seems you have Fink installed on your system -- This could potentially cause issues with MacPorts. We'd recommend you'd \
ui_warn "it seems you have Fink installed on your system -- This could potentially cause issues with MacPorts. We'd recommend you \
either uninstall it, or move it from /sw for now."
success_fail 0
@@ -343,19 +355,15 @@ namespace eval diagnose {
# None
set apps [reclaim::get_info]
set apps [registry::entry imaged]
array set activeApps {}
set totalFiles 0
foreach app $apps {
set name [lindex $app 0]
set active [lindex $app 4]
set files [registry::port_registered $name]
if {$active} {
set activeApps($name) $files
set files [$app files]
if {[$app state] eq "installed"} {
set activeApps([$app name]) $files
incr totalFiles [llength $files]
}
}
@@ -363,7 +371,7 @@ namespace eval diagnose {
set fancyOutput [expr { ![macports::ui_isset ports_debug] \
&& ![macports::ui_isset ports_verbose] \
&& [info exists macports::ui_options(progress_generic)] \
&& ${diagnose::quiet} == 0}]
&& !${diagnose::quiet}}]
if {$fancyOutput} {
set progress $macports::ui_options(progress_generic)
@@ -372,7 +380,7 @@ namespace eval diagnose {
if {$totalFiles > 0} {
if {$fancyOutput} {
output "files installed by ports on disk"
if {${diagnose::quiet} == 0} {
if {!${diagnose::quiet}} {
# we need a newline here or the progress bar will overwrite the line
ui_msg ""
}
@@ -430,24 +438,14 @@ namespace eval diagnose {
# Returns:
# None
set apps [reclaim::get_info]
set apps [registry::entry imaged]
foreach app $apps {
set name [lindex $app 0]
set version [lindex $app 1]
set revision [lindex $app 2]
set variants [lindex $app 3]
set epoch [lindex $app 5]
output "'${name} @${version}_${revision}${variants}'s tarball on disk"
set ref [registry::open_entry $name $version $revision $variants $epoch]
set image_dir [registry::property_retrieve $ref location]
if {![file exists $image_dir]} {
ui_warn "couldn't find the archive for '$name'. Please uninstall and reinstall this application."
set name [$app name]
output "'${name} @[$app version]_[$app revision][$app variants]'s tarball on disk"
if {![file exists [$app location]]} {
ui_warn "couldn't find the archive for '$name'. Please uninstall and reinstall this port."
success_fail 0
} else {
success_fail 1
@@ -468,7 +466,7 @@ namespace eval diagnose {
output "dylibs in /usr/local/lib"
if {[glob -nocomplain -directory "/usr/local/lib" *.dylib *.la *.prl] ne ""} {
ui_warn "found dylib's in your /usr/local/lib directory. These are known to cause problems. We'd recommend \
ui_warn "found dylibs in your /usr/local/lib directory. These are known to cause problems. We'd recommend \
you remove them."
success_fail 0
@@ -556,9 +554,9 @@ namespace eval diagnose {
# Returns:
# None
output "MacPort's location"
output "MacPorts' location"
if {[file exists ${macports::prefix}/bin/port] == 0} {
if {![file exists ${macports::prefix}/bin/port]} {
ui_error "the port command was not found in ${macports::prefix}/bin. This can potentially cause errors. It's recommended you move it back to ${macports::prefix}/bin."
success_fail 0
return
@@ -578,7 +576,7 @@ namespace eval diagnose {
output "for '$app'"
if {[file exists /usr/bin/$app] == 0} {
if {![file exists /usr/bin/$app]} {
ui_error "$app is needed by MacPorts to function normally, but wasn't found on this system. We'd recommend \
installing it for continued use of MacPorts."
success_fail 0
@@ -603,12 +601,16 @@ namespace eval diagnose {
set mac_version ${macports::macosx_version}
set xcode_current ${macports::xcodeversion}
set xcode_versions $config(xcode_version_$mac_version)
if {[info exists config(xcode_version_$mac_version)]} {
set xcode_versions $config(xcode_version_$mac_version)
} else {
ui_warn "No Xcode version info was found for your OS version."
success_fail 0
return
}
if {$xcode_current in $xcode_versions} {
success_fail 1
return
} else {
ui_error "currently installed version of Xcode, $xcode_current, is not supported by MacPorts. \
For your currently installed system, only the following versions of Xcode are supported: \
@@ -617,45 +619,23 @@ namespace eval diagnose {
}
}
proc make_xcode_config {path} {
proc check_xcode_config {path} {
# Checks to see if xcode_versions.ini exists. If it does, it returns. If it doesn't, then it creats a defult config file.
# Checks to see if xcode_versions.ini exists. If it does, it returns. If it doesn't, then it raises an error.
#
# Args:
# None
# Returns:
# None
if {[file exists $path] == 0} {
if {![file exists $path]} {
ui_error "No configuration file found at $path. Please run,
\"port selfupdate\""
exit
error "missing [file tail $path]"
}
}
proc make_user_config {path} {
# Builds a config file for the user using all default parameters if needed.
#
# Args:
# None
# Returns:
# None
if {[file exists $path] == 0} {
ui_warn "No configuration file found at $path. Creating generic config file."
set fd [open $path w]
puts $fd "macports_location=${macports::prefix}"
puts $fd "profile_path=${macports::user_home}/.bash_profile"
puts $fd "shell_location=/bin/bash"
close $fd
}
}
proc get_config {config_options parser_options path} {
# Reads in and parses the configuration file passed in to $path. After parsing, all variables found are assigned
@@ -668,6 +648,10 @@ namespace eval diagnose {
# Returns:
# None.
if {![file isfile $path]} {
return
}
upvar $config_options config
set fd [open $path r]
@@ -676,10 +660,10 @@ namespace eval diagnose {
close $fd
foreach line $data {
foreach line $data {
# Ignore comments
if {[string index $line 0] eq "#" } {
if {[string index $line 0] eq "#"} {
continue
}
@@ -694,7 +678,7 @@ namespace eval diagnose {
} elseif {[lindex $tokens 0] eq ""} {
continue
} else {
} elseif {![string match xcode_version_* [lindex $tokens 0]]} {
ui_error "unrecognized config option in file $path: [lindex $tokens 0]"
}
}
@@ -715,16 +699,16 @@ namespace eval diagnose {
set path ${macports::user_path}
set split [split $path :]
if {"$port_loc/bin" in $split && "$port_loc/sbin" in $split } {
if {"$port_loc/bin" in $split && "$port_loc/sbin" in $split} {
if {[lindex $split 0] ne "$port_loc/bin"} {
ui_warn "$port_loc/bin is not first in your PATH environmental variable. This may or may not \
ui_warn "$port_loc/bin is not first in your PATH environment variable. This may or may not \
cause problems in the future."
}
return
} else {
ui_warn "your environmental \$PATH variable does not currently include, $port_loc/bin, which is where port is located. \
ui_warn "your \$PATH environment variable does not currently include, $port_loc/bin, which is where port is located. \
Would you like to add $port_loc/bin to your \$PATH variable now? \[Y/N\]"
set input [gets stdin]
@@ -734,18 +718,19 @@ namespace eval diagnose {
# share code?
ui_msg "Attempting to add $port_loc/bin to $profile_path"
if {[file exists $profile_path] == 1} {
set fd [open $profile_path a]
if {[file exists $profile_path]} {
if {[file writable $profile_path]} {
set fd [open $profile_path a]
puts $fd "export PATH=$port_loc/bin:$port_loc/sbin:\$PATH"
close $fd
ui_msg "Added PATH properly. Please open a new terminal window to load the modified ${profile_path}."
} else {
ui_error "Can't write to ${profile_path}."
}
} else {
ui_error "$profile_path does not exist."
}
puts $fd "export PATH=$port_loc/bin:$port_loc/sbin:\$PATH"
close $fd
ui_msg "Added PATH properly. Please execute, 'source $profile_path' in a new terminal window."
} elseif {$input eq "n" || $input eq "N"} {
ui_msg "Not fixing your \$PATH variable."
-3
View File
@@ -2773,9 +2773,6 @@ proc action_setrequested { action portlist opts } {
}
proc action_diagnose { action portlist opts } {
if {[prefix_unwritable]} {
return 1
}
macports::diagnose_main $opts
return 0
}