Workflow for not blowing away state (was Re: [96136] trunk/base)

Jeremy Huddleston Sequoia jeremyhu at macports.org
Wed Sep 12 15:13:41 PDT 2012


I really liked the old mtime approach.  It made development easier.  If I have a bug in destroot, I want to just retry destroot without having to rebuild.  I used to accomplish this by touching (or editing) the state file after editing the Portfile, but with this change to checksums, I can no longer trick base this way.

I really don't want to use ports_ignore_different because I don't want to set it globally, and 75% of the time, I'm sure I'll mistype it.  I'll either think it's port_ instead of ports_ or misspell something else, and then my state will be gone.

Is there an equivalently easy way to get base to think that the Portfile isn't newer?  What is everyone else's new workflow?

--Jeremy


On Aug 1, 2012, at 13:28, cal at macports.org wrote:

> Revision: 96136
>          https://trac.macports.org/changeset/96136
> Author:   cal at macports.org
> Date:     2012-08-01 13:28:35 -0700 (Wed, 01 Aug 2012)
> Log Message:
> -----------
> Don't rely on mtime of statefile and Portfile
> 
> Traditionally, MacPorts used mtimes of both the statefile and the
> Portfile to detect whether a Portfile was updated between builds and a
> previously started build should not be continued, but restarted.
> 
> However, since we do sync modification times from the repository to the
> users there exists a situation where this check is not correct (see
> #29223 for an explanation).
> 
> This change drops checking the mtime in favor of recording a sha256 sum
> of the Portfile when starting a new build as first line of the
> statefile. If the checksum doesn't match, the build is restarted.
> 
> Since a check for changed variants did rely on the statefile being empty
> for fresh builds, I have re-written this test to consider the statefile
> "empty" if no lines match "variant: .*".
> 
> This also updates man 1 port.
> 
> All flags affecting the check (-f, -o) should continue to work.
> 
> The change of the statefile format will cause all builds started before
> installing this code to be restarted.
> 
> Closes #29223.
> 
> Modified Paths:
> --------------
>    trunk/base/doc/port.1
>    trunk/base/src/port/port.tcl
>    trunk/base/src/port1.0/portutil.tcl
> 
> Modified: trunk/base/doc/port.1
> ===================================================================
> --- trunk/base/doc/port.1	2012-08-01 20:08:37 UTC (rev 96135)
> +++ trunk/base/doc/port.1	2012-08-01 20:28:35 UTC (rev 96136)
> @@ -252,7 +252,7 @@
> .It Fl f
> force mode (ignore state file)
> .It Fl o
> -honor state files older than Portfile
> +honor state files even if the Portfile has been modified since (called -o because it used to mean "older")
> .It Fl s
> source-only mode (build and install from source, do not attempt to fetch binary archives)
> .It Fl b
> 
> Modified: trunk/base/src/port/port.tcl
> ===================================================================
> --- trunk/base/src/port/port.tcl	2012-08-01 20:08:37 UTC (rev 96135)
> +++ trunk/base/src/port/port.tcl	2012-08-01 20:28:35 UTC (rev 96136)
> @@ -4315,7 +4315,7 @@
>                         set global_options(ports_force) yes
>                     }
>                     o {
> -                        set global_options(ports_ignore_older) yes
> +                        set global_options(ports_ignore_different) yes
>                     }
>                     n {
>                         set global_options(ports_nodeps) yes
> 
> Modified: trunk/base/src/port1.0/portutil.tcl
> ===================================================================
> --- trunk/base/src/port1.0/portutil.tcl	2012-08-01 20:08:37 UTC (rev 96135)
> +++ trunk/base/src/port1.0/portutil.tcl	2012-08-01 20:28:35 UTC (rev 96136)
> @@ -1637,7 +1637,7 @@
> # open_statefile
> # open file to store name of completed targets
> proc open_statefile {args} {
> -    global workpath worksymlink place_worksymlink subport portpath ports_ignore_older ports_dryrun \
> +    global workpath worksymlink place_worksymlink subport portpath ports_ignore_different ports_dryrun \
>            usealtworkpath altprefix env applications_dir subbuildpath
> 
>     if {$usealtworkpath} {
> @@ -1680,22 +1680,32 @@
> 
>     # flock Portfile
>     set statefile [file join $workpath .macports.${subport}.state]
> +    set fresh_build yes
> +    set checksum_portfile [sha256 file ${portpath}/Portfile]
>     if {[file exists $statefile]} {
> +        set fresh_build no
>         if {![file writable $statefile] && ![tbool ports_dryrun]} {
>             return -code error "$statefile is not writable - check permission on port directory"
>         }
>         if {[file mtime ${portpath}/Portfile] > [clock seconds]} {
>             return -code error "Portfile is from the future - check date and time of your system"
>         }
> -        if {!([info exists ports_ignore_older] && $ports_ignore_older == "yes") && [file mtime $statefile] < [file mtime ${portpath}/Portfile]} {
> -            if {![tbool ports_dryrun]} {
> -                ui_notice "Portfile changed since last build; discarding previous state."
> -                chownAsRoot $subbuildpath
> -                delete $workpath
> -                file mkdir $workpath
> -            } else {
> -                ui_notice "Portfile changed since last build but not discarding previous state (dry run)"
> +        if {![tbool ports_ignore_different]} {
> +            set readfd [open $statefile r]
> +            gets $readfd checksum_statefile
> +            if {$checksum_portfile != $checksum_statefile} {
> +                ui_debug "Checksum recorded in statefile \"$checksum_statefile\" differs from Portfile checksum \"$checksum_portfile\""
> +                if {![tbool ports_dryrun]} {
> +                    ui_notice "Portfile changed since last build; discarding previous state."
> +                    chownAsRoot $subbuildpath
> +                    delete $workpath
> +                    file mkdir $workpath
> +                    set fresh_build yes
> +                } else {
> +                    ui_notice "Portfile changed since last build but not discarding previous state (dry run)"
> +                }
>             }
> +            close $readfd
>         }
>     } elseif {[tbool ports_dryrun]} {
>         set statefile /dev/null
> @@ -1715,6 +1725,9 @@
>             }
>         }
>     }
> +    if {[tbool fresh_build]} {
> +        puts $fd $checksum_portfile
> +    }
>     return $fd
> }
> 
> @@ -1754,19 +1767,20 @@
> 
>     array set upoldvariations {}
> 
> -    seek $fd 0 end
> -    if {[tell $fd] == 0} {
> -        # Statefile is empty, skipping further tests
> -        return 0
> -    }
> -
> +    set variants_found no
>     seek $fd 0
>     while {[gets $fd line] >= 0} {
>         if {[regexp "variant: (.*)" $line match name]} {
>             set upoldvariations([string range $name 1 end]) [string range $name 0 0]
> +            set variants_found yes
>         }
>     }
> 
> +    if {![tbool variants_found]} {
> +        # Statefile is "empty", skipping further tests
> +        return 0
> +    }
> +
>     set mismatch 0
>     if {[array size upoldvariations] != [array size upvariations]} {
>         set mismatch 1
> _______________________________________________
> macports-changes mailing list
> macports-changes at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo/macports-changes



More information about the macports-dev mailing list