source: branches/gsoc09-logging/base/src/port1.0/portlivecheck.tcl @ 52218

Last change on this file since 52218 was 52218, checked in by enl@…, 11 years ago

Merge from trunk

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.3 KB
Line 
1# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:filetype=tcl:et:sw=4:ts=4:sts=4
2# portlivecheck.tcl
3#
4# $Id: portlivecheck.tcl 52218 2009-06-12 08:57:53Z enl@macports.org $
5#
6# Copyright (c) 2005-2006 Paul Guyot <pguyot@kallisys.net>,
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are
11# met:
12#
13# 1. Redistributions of source code must retain the above copyright
14#    notice, this list of conditions and the following disclaimer.
15# 2. Redistributions in binary form must reproduce the above copyright
16#    notice, this list of conditions and the following disclaimer in the
17#    documentation and/or other materials provided with the distribution.
18# 3. Neither the name of Apple Computer, Inc. nor the names of its
19#    contributors may be used to endorse or promote products derived from
20#    this software without specific prior written permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33#
34
35package provide portlivecheck 1.0
36package require portutil 1.0
37package require portfetch 1.0
38
39set org.macports.livecheck [target_new org.macports.livecheck portlivecheck::livecheck_main]
40target_runtype ${org.macports.livecheck} always
41target_state ${org.macports.livecheck} no
42target_provides ${org.macports.livecheck} livecheck
43target_requires ${org.macports.livecheck} main
44
45namespace eval portlivecheck {
46}
47
48# define options
49options livecheck.url livecheck.type livecheck.check livecheck.md5 livecheck.regex livecheck.name livecheck.distname livecheck.version
50
51# defaults
52default livecheck.url {$homepage}
53default livecheck.check default
54default livecheck.type default
55default livecheck.md5 ""
56default livecheck.regex ""
57default livecheck.name default
58default livecheck.distname default
59default livecheck.version {$version}
60
61# Deprecation
62option_deprecate livecheck.check livecheck.type
63
64proc portlivecheck::livecheck_main {args} {
65    global livecheck.url livecheck.type livecheck.md5 livecheck.regex livecheck.name livecheck.distname livecheck.version
66    global fetch.user fetch.password fetch.use_epsv fetch.ignore_sslcert
67    global homepage portpath workpath
68    global master_sites name distfiles
69
70    set updated 0
71    set updated_version "unknown"
72    set has_master_sites [info exists master_sites]
73    set has_homepage [info exists homepage]
74
75    set tempfile [mktemp "/tmp/mports.livecheck.XXXXXXXX"]
76    set port_moddate [file mtime ${portpath}/Portfile]
77
78    ui_debug "Portfile modification date is [clock format $port_moddate]"
79    ui_debug "Port (livecheck) version is ${livecheck.version}"
80
81    # Copied over from portfetch in parts
82    set fetch_options {}
83    if {[string length ${fetch.user}] || [string length ${fetch.password}]} {
84        lappend fetch_options -u
85        lappend fetch_options "${fetch.user}:${fetch.password}"
86    }
87    if {${fetch.use_epsv} != "yes"} {
88        lappend fetch_options "--disable-epsv"
89    }
90    if {${fetch.ignore_sslcert} != "no"} {
91        lappend fetch_options "--ignore-ssl-cert"
92    }
93
94    # Check _resources/port1.0/livecheck for available types.
95    set types_dir [getdefaultportresourcepath "port1.0/livecheck"]
96    if {[catch {set available_types [glob -directory $types_dir -tails -types f *.tcl]} result]} {
97        return -code 1 "No available types were found. Check '$types_dir'."
98    }
99
100    # Convert available_types from a list of files (e.g., { freshmeat.tcl
101    # gnu.tcl ... }) into a string in the format "type|type|..." (e.g.,
102    # "freshmeat|gnu|...").
103    set available_types [regsub -all {\.tcl} [join $available_types |] {}]
104
105    if {${livecheck.type} eq "default"} {
106        # Determine the default type from the mirror.
107        if {$has_master_sites} {
108            foreach {master_site} ${master_sites} {
109                if {[regexp "^($available_types)(?::(\[^:\]+))?" ${master_site} _ site subdir]} {
110                    if {${subdir} ne "" && ${livecheck.name} eq "default"} {
111                        set livecheck.name ${subdir}
112                    }
113                    set livecheck.type ${site}
114
115                    break
116                }
117            }
118        }
119        # If the default type cannot be determined from the mirror, use the
120        # fallback.
121        if {${livecheck.type} eq "default"} {
122            set livecheck.type "fallback"
123        }
124    }
125    # If livecheck.name is still "default", set it to $name.
126    if {${livecheck.name} eq "default"} {
127        set livecheck.name $name
128    }
129    if {[lsearch -exact [split $available_types "|"] ${livecheck.type}] != -1} {
130        # Load the defaults from _resources/port1.0/livecheck/${livecheck.type}.tcl.
131        set defaults_file "$types_dir/${livecheck.type}.tcl"
132        ui_debug "Loading the defaults from '$defaults_file'"
133        if {[catch {source $defaults_file} result]} {
134            return -code 1 "The defaults could not be loaded from '$defaults_file'."
135        }
136    }
137
138    # de-escape livecheck.url
139    set livecheck.url [join ${livecheck.url}]
140
141    switch ${livecheck.type} {
142        "regex" -
143        "regexm" {
144            # single and multiline regex
145            ui_debug "Fetching ${livecheck.url}"
146            if {[catch {eval curl fetch $fetch_options {${livecheck.url}} $tempfile} error]} {
147                ui_error "cannot check if $name was updated ($error)"
148                set updated -1
149            } else {
150                # let's extract the version from the file.
151                set chan [open $tempfile "r"]
152                set updated -1
153                set the_re [join ${livecheck.regex}]
154                ui_debug "The regex is \"$the_re\""
155                if {${livecheck.type} == "regexm"} {
156                    set data [read $chan]
157                    if {[regexp $the_re $data matched updated_version]} {
158                        if {$updated_version != ${livecheck.version}} {
159                            set updated 1
160                        } else {
161                            set updated 0
162                        }
163                        ui_debug "The regex matched \"$matched\", extracted \"$updated_version\""
164                    }
165                } else {
166                    set updated_version 0
167                    set foundmatch 0
168                    while {[gets $chan line] >= 0} {
169                        if {[regexp $the_re $line matched upver]} {
170                            set foundmatch 1
171                            if {$updated_version == 0 || [rpm-vercomp $upver $updated_version] > 0} {
172                                set updated_version $upver
173                            }
174                            ui_debug "The regex matched \"$matched\", extracted \"$upver\""
175                        }
176                    }
177                    if {$foundmatch == 1} {
178                        if {$updated_version == 0} {
179                            set updated -1
180                        } elseif {$updated_version != ${livecheck.version}} {
181                            set updated 1
182                        } else {
183                            set updated 0
184                        }
185                    }
186                }
187                close $chan
188                if {$updated < 0} {
189                    ui_error "cannot check if $name was updated (regex didn't match)"
190                }
191            }
192        }
193        "md5" {
194            ui_debug "Fetching ${livecheck.url}"
195            if {[catch {eval curl fetch $fetch_options {${livecheck.url}} $tempfile} error]} {
196                ui_error "cannot check if $name was updated ($error)"
197                set updated -1
198            } else {
199                # let's compute the md5 sum.
200                set dist_md5 [md5 file $tempfile]
201                if {$dist_md5 != ${livecheck.md5}} {
202                    ui_debug "md5sum for ${livecheck.url}: $dist_md5"
203                    set updated 1
204                }
205            }
206        }
207        "moddate" {
208            set port_moddate [file mtime ${portpath}/Portfile]
209            if {[catch {set updated [curl isnewer ${livecheck.url} $port_moddate]} error]} {
210                ui_error "cannot check if $name was updated ($error)"
211                set updated -1
212            } else {
213                if {!$updated} {
214                    ui_debug "${livecheck.url} is older than Portfile"
215                }
216            }
217        }
218        "none" {
219        }
220        default {
221            ui_error "unknown livecheck.type ${livecheck.type}"
222        }
223    }
224
225    file delete -force $tempfile
226
227    if {${livecheck.type} != "none"} {
228        if {$updated > 0} {
229            ui_msg "$name seems to have been updated (port version: ${livecheck.version}, new version: $updated_version)"
230        } elseif {$updated == 0} {
231            ui_info "$name seems to be up to date"
232        }
233    }
234}
Note: See TracBrowser for help on using the repository browser.