Helpful tools for searching /usr/ports/UPDATING

I enjoy installing software via ports. In the past I would occasionally get hung up with a problem that I would try to solve via google searching the web or searching this forum. Then I found almost all of the info I needed to solve my problems was contained in the /usr/ports/UPDATING file -- which is like a diary of all of the small interdependency issues you need to be aware of to successfully run certain applications. I love this file now and it is the first thing I view after I portsnap fetch update.

The file is a long one and it can take a long time to just manually scan it for relevant info. But I found this website http://updating.braincomb.com/ by Aleksandr Melentiev -- which updates with that file every hour and lets you rapidly search it for what you want.

I was looking for a similar way to search /usr/ports/UPDATING from the command line (more comprehensive than grep) -- and ended up writing my own script in Python that allows you to search /usr/ports/UPDATING for a case-insensitive string (not meant for searching by date -- just by topic (i.e. php, perl, mysql, etc.). It prints to both the terminal and to a text file in your home directory (you can personalize that). I am not a great coder but feel free to use.

Code:
#! /usr/local/bin/python3.4

# Built for Python 3.4
# Script to search /usr/ports/UPDATING on PC-BSD and FreeBSD
# Prints to both the terminal and to a text file in your home directory

initialSplash = """\n+--------------------------------+
|   Search /usr/ports/UPDATING   |
+--------------------------------+

!! You last updated the ports tree on: """

print(initialSplash)

# open text file to read
with open('/usr/ports/UPDATING','r') as original:     

    # read the file and split the string into a list separated by the 2 at the start of the date
    originalString = original.read()
    categoriesList = originalString.split('\n2')
    
    # cut the last line which has the last port update date/time
    lastUpdate = categoriesList[len(categoriesList) - 1].split('\n$F')
    
    searchCue = "!! Search for ==> "
    
    print('\n$F' + lastUpdate[1] + '\n\n' + searchCue)
    
    searchString = input()

    numberOfItems = 0
    
    # open new file to write results to
    writeToFile = open("/usr/home/currentPortsUpdating.txt", "w")
    writeToFile.write("/usr/ports/UPDATING\n\n$F" + lastUpdate[1] + "\n")
    writeToFile.write('\n!! Search for: "' + searchString + '"\n')
    
    # for each of the items in the list, print the item that contains the search string - case insensitive
    for x in range(len(categoriesList)):

        if (searchString in categoriesList[x]) or (searchString in categoriesList[x].upper()) or (searchString in categoriesList[x].lower()):

            # remember to add back the newline and 2
            print('\n2' + categoriesList[x])
            
            # add this also to our text file
            writeToFile.write('\n2' + categoriesList[x])
            
            numberOfItems += 1
            
    # close our text file
    writeToFile.write('\n !! Found ' + str(numberOfItems) + ' items that include "' + searchString + '".\n')
    writeToFile.close()

print('\n !! Found ' + str(numberOfItems) + ' items that include "' + searchString + '".\n')
 
The method I use is a combination of several pkg commands; not in a script executable file, I'm not so skilled in sh programming, if you are skilled you can write it. The method is as follow

  • Get all installed list of packages with pkg info -a or pkg query '%n %v'.
  • For each one get the installation date with pkg query %t <package>.
  • Get the updating entry relative to each package starting from its installation date with pkg updating -d <date> <package> (for <package> parameter use the result of pkg query %n or it doesn't work as expected, and for the previous entry too).
  • Remove duplicated entries (and sort) in the resulting list and display it.

Sometimes there are some entries in /usr/ports/UPDATING not related to specific port or that contain wildcards, those entries are not displayed by command like pkg updating so there is one more step to add in the list: finding all those entries starting from one arbitrary point in time (last time you ran the script?) and display them as a special list. The better is to show a check list (TUI/GUI) and let the user to remove them when 'acknowledged' (and avoid displaying them next time you run the script).
 
Unfortunately the UPDATING file is quite free format unlike the vulnerability database that is in XML with strict rules what the fields can contain. This means that some entries in UPDATING are hard to match by just searching for entries based on the raw list of installed package names.
 
Without looking, I believe every instruction regarding updating ports instructs you to read /usr/ports/UPDATING immediately before doing anything else. Doing so means you are always aware of situations immediately and you don't have to search back through hundreds of records and vi/vim is the only tool you need.
 
Also, some entries in UPDATING are to the system, not a specific port.

pkg info or pkg info -a works just like the old version of those commands.

It is best to keep all ports updated. Updating only certain ones can break dependencies. If all ports are kept updated, only the most-recent date of change is needed to start looking through UPDATING. That can be obtained with date -r `pkg query %t | sort | tail -n1` "+%Y%m%d".
 
Dead thread but.... I find these aliases useful:

alias UPDATE 'portsnap fetch update && date -r [ICODE]pkg query %t | sort | tail -n1[/ICODE] "+%Y%m%d" | xargs pkg updating -d'
and
alias UPDATING 'date -r [ICODE]pkg query %t | sort | tail -n1[/ICODE] "+%Y%m%d" | xargs pkg updating -d'
 
Back
Top