Skip to content

Commit 2f3dc5a

Browse files
committed
port.tcl: Offer automated switch to git-based source
1 parent 527841c commit 2f3dc5a

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed

src/port/port.tcl

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3927,6 +3927,161 @@ proc action_echo { action portlist opts } {
39273927
return 0
39283928
}
39293929

3930+
proc offer_clone {} {
3931+
global macports::os_platform macports::os_major macports::os_arch \
3932+
macports::sources macports::autoconf::rsync_path \
3933+
macports:rsync_options macports::getindex macports::sources_default \
3934+
macports::sudo_user macports::prefix macports::portdbpath
3935+
3936+
# CHECK IF SOURCES.CONF IS STILL DEFAULT (INDICATING THAT USER IS FIRST TIME CONTRIBUTOR)
3937+
set confpath "${macports::prefix}/etc/macports/sources.conf"
3938+
if {[catch {exec [macports::findBinary diff] "-q" $confpath "$confpath.default"} _]} {
3939+
set tempfd [open "${macports::portdbpath}/contrib" w]
3940+
close $tempfd
3941+
return 0
3942+
}
3943+
3944+
# OFFER GIT-BASED SOURCE AND ASK FOR PATH
3945+
set retvalue [$macports::ui_options(questions_yesno) "You do not seem have a working copy of the macports-ports git repository, which is required to contribute this change." "clone" {} {y} 0 "Create one now?"]
3946+
if {$retvalue == 1} {
3947+
# quit as user answered 'no'
3948+
set tempfd [open "${macports::portdbpath}/contrib" w]
3949+
close $tempfd
3950+
return 0
3951+
}
3952+
3953+
set path [$macports::ui_options(questions_input) "Where do you want to create your working copy?" [file join ~ macports-ports] 0]
3954+
3955+
# SWITCH TO SUDO_USER UID AND GID
3956+
set oldeuid [geteuid]
3957+
set oldgid [getgid]
3958+
if {[info exists macports::sudo_user]} {
3959+
set username ${macports::sudo_user}
3960+
} else {
3961+
set username [exec id -un]
3962+
}
3963+
set useruid [name_to_uid $username]
3964+
set usergid [uname_to_gid $username]
3965+
if {$oldeuid == 0} {
3966+
setegid $usergid
3967+
seteuid $useruid
3968+
}
3969+
3970+
# Make sure that folder is empty
3971+
set temp [file normalize $path]
3972+
if {[file exists $temp]} {
3973+
set len 0
3974+
fs-traverse _ $temp {
3975+
if {$len == 1} {
3976+
return -code error "path: $temp already exists and is not an empty directory."
3977+
}
3978+
incr len
3979+
}
3980+
}
3981+
3982+
# WALK DOWN FROM PATH TO ROOT AND ASK FOR GROUP X PERMISSIONS IF NEEDED
3983+
set paths {}
3984+
while {$temp ne [file normalize /]} {
3985+
if {![file exists $temp]} {
3986+
file mkdir $temp
3987+
}
3988+
if {[expr {[string index [file attributes $path -permissions] end] & 1}] == 0} {
3989+
lappend paths $temp
3990+
}
3991+
set temp [file dirname $temp]
3992+
}
3993+
3994+
if {[llength $paths] > 0} {
3995+
set allow [$macports::ui_options(questions_yesno) "The 'macports' user needs search access to $path to use ports in
3996+
this directory. The following directories will be changed to include 'x'
3997+
permissions for group and others:\n" "allow" $paths {y} 0 "Do you want to allow this?"]
3998+
if {$allow == 1} {
3999+
# quit as user answered 'no'
4000+
set tempfd [open "${macports::portdbpath}/contrib" w]
4001+
close $tempfd
4002+
return 0
4003+
}
4004+
foreach path $paths {
4005+
file attributes $path -permissions [expr {[file attributes $path -permissions] | 1}]
4006+
}
4007+
}
4008+
4009+
# CREATE GIT SOURCE BY CLONING MACPORTS-PORTS
4010+
# The small depth is for performance (it also implies --single-branch)
4011+
set url https://github.com/macports/macports-ports.git
4012+
if {[catch {system -nodup "[macports::findBinary git] clone --depth 1 $url $path"} result]} {
4013+
ui_debug $::errorInfo
4014+
ui_error "git clone: $result"
4015+
return 1
4016+
}
4017+
4018+
# COPY INDEXFILE FROM OLD SOURCE TO GIT SOURCE
4019+
set default_source_url [lindex $sources_default 0]
4020+
set indexfile [macports::getindex $default_source_url]
4021+
4022+
if {[catch {file copy -force $indexfile $path} error]} {
4023+
ui_debug $::errorInfo
4024+
ui_error "file copy: $error"
4025+
return -code error "Copying PortIndex to new git-based source failed"
4026+
}
4027+
4028+
# EDIT SOURCES.CONF TO USE GIT SOURCE
4029+
if {![file exists $temp]} {
4030+
return -code error "sources.conf not found in $confpath"
4031+
}
4032+
4033+
# Construct sed command
4034+
set cmdline "[macports::findBinary sed] -E s/(^rsync)/#\1/g"
4035+
if {[catch {set tmpfile [mkstemp "/tmp/sources.conf.sed.XXXXXX"]} error]} {
4036+
ui_debug $::errorInfo
4037+
ui_error "mkstemp: $error"
4038+
return -code error "mkstemp failed"
4039+
}
4040+
set tmpfd [lindex $tmpfile 0]
4041+
set tmpfile [join [lrange $tmpfile 1 end]]
4042+
set attributes [file attributes $confpath]
4043+
lappend cmdline "<${confpath}" ">@$tmpfd"
4044+
# Comment out the rsync line
4045+
if {[catch {exec -ignorestderr -- {*}$cmdline} error]} {
4046+
ui_debug $::errorInfo
4047+
ui_error "sed: $error"
4048+
file delete "$tmpfile"
4049+
close $tmpfd
4050+
return -code error "sed sed(1) failed"
4051+
}
4052+
4053+
# Write the new source
4054+
puts $tmpfd "file://[file normalize $path] \[default\]"
4055+
4056+
if {[geteuid] != [getuid]} {
4057+
seteuid $oldeuid
4058+
setegid $oldgid
4059+
}
4060+
4061+
# Replace the old sources.conf with the new one
4062+
if {[catch {file rename -force $tmpfile $confpath} error]} {
4063+
ui_debug $::errorInfo
4064+
ui_error "move: $error"
4065+
file delete "$tmpfile"
4066+
return -code error "sources.conf overwrite failed"
4067+
}
4068+
4069+
# Restore sources.conf attributes
4070+
file attributes $confpath {*}$attributes
4071+
4072+
# Update the ports tree
4073+
try {
4074+
mportsync
4075+
} catch {{*} eCode eMessage} {
4076+
return -code error "Couldn't sync the ports tree: $eMessage"
4077+
}
4078+
4079+
ui_msg "Your /opt/local/etc/macports/sources.conf has been updated to use the git repository."
4080+
4081+
set tempfd [open "${macports::portdbpath}/contrib" w]
4082+
close $tempfd
4083+
return "[file dirname $indexfile] [file normalize $path]"
4084+
}
39304085

39314086
proc action_portcmds { action portlist opts } {
39324087
# Operations on the port's directory and Portfile
@@ -3984,6 +4139,15 @@ proc action_portcmds { action portlist opts } {
39844139
array unset env *
39854140
array set env [array get boot_env]
39864141

4142+
# Offer setting up switch to git-based source for first time contributors
4143+
if {![file exists ${macports::portdbpath}/contrib]} {
4144+
# Offer clone will return the old source path and new source path. Redirect portfile to new one
4145+
set result [offer_clone]
4146+
if {[llength $result] > 1} {
4147+
regsub [lindex $result 0] $portfile [lindex $result 1] portfile
4148+
}
4149+
}
4150+
39874151
# Find an editor to edit the portfile
39884152
set editor ""
39894153
set editor_var "ports_${action}_editor"

0 commit comments

Comments
 (0)