= Tips and Tricks for committers = This page provides some useful hints how to work with our infrastructure. And they can also make your work a lot easier. [[PageOutline(2,Contents,inline)]] == Apply patches directly from Trac URL == === Installation === Add the following functions to your `.bashrc` in order to apply patches directly from Trac. {{{ #!sh function trac-get { local url=$1 local dir=$2 if [ -z $dir ]; then dir=. fi curl "$url?format=raw" --create-dirs -o $dir/$(basename $1) } function trac-patch { local cmd="" while [[ $1 == -* ]]; do if [ "$1" == "--" ]; then break fi cmd="$cmd $1" shift done if [ -z $cmd ]; then cmd="--strip 0" fi trac-get $1 patch $cmd < $(basename $1) } }}} === Usage === Use like this: 1. Copy the URL to the patch from the Trac ticket page 1. Switch to the ports directory {{{ $ cd $(port dir foo) }}} 1. Apply the patch {{{ $ trac-patch https://trac.macports.org/attachment/ticket/.../Portfile.diff }}} You can also add options to `trac-patch` which will get passed through to the patch tool. This is especially useful when the patch needs another prefix level. {{{ $ trac-patch -p1 https://trac.macports.org/attachment/ticket/.../Portfile.diff }}} If you don't add any option, `-p0` is used as a default. This should be the most common case. `trac-get` can also download to another directory. If the directory does not yet exist, it will be created. Just add a second parameter with the name of the directory. If you omit the second parameter, the current directory is used. {{{ $ trac-get https://trac.macports.org/attachment/ticket/.../Portfile new-port }}} == Do Explorative Programming in tclsh with Readline Support == #explore tclsh does not offer readline support by itself, which is quite annoying. When writing portfiles or tinkering with changes to Macports base, I need to experiment in a Tcl shell all the time to tests small things. But for that, command history and Emacs-like navigation within the line are essential. Unfortunately tclsh does not offer this. You can also use Emacs’ tcl-mode: from within a tcl buffer, the tcl shell is just a {{{C-t}}} away. More info in [http://wiki.tcl.tk/_/search?S=emacs tcler’s wiki]. Solution: use port {{{rlwrap}}} together with tclsh. When you invoke tclsh via rlwrap you get all the convenience you know from bash. {{{ rlwrap tclsh }}} Or, put even an alias into ~/.bashrc {{{ alias tclsh='rlwrap tclsh' }}} and don't think about it ever again. If you want to test MacPorts Tcl extensions, you need to require the appropriate packages. For access to the 'strsed', 'reinplace', and other macport commands, put the following into ~/bin/macports_testing.tcl: {{{ package require macports set portarchivemode no mportinit #package require port package require Pextlib }}} [Note, Oct 2009] There may be a bug in the port 1.0 package, see http://lists.macosforge.org/pipermail/macports-dev/2009-September/010132.html Then source the file in the Apple-supplied tclsh, i.e.: {{{ $ rlwrap /usr/bin/tclsh % source ~/bin/macports_testing.tcl /opt/local % strsed "foo" "s/f/m/" moo % }}} Check [wiki:MacPortsShell self contained script] too. == Debugging Tcl scripts == #debugger Tcl scripts can be debugged with the `expect` tool, which provides a debugging interface similar to gdb for those who are familiar with that. For a command overview, just type `h` at the prompt. Run with: {{{ $ expect -D1 }}} For example: {{{ $ expect -D1 foo.tcl -bar 1: proc main {args} { ... dbg1.0> }}} == Portfile syntax highlighting == #syntax-highlighting * [BbeditLanguageModule BBEdit, TextWrangler] * [https://github.com/textmate/macports.tmbundle TextMate] * [https://svn.macports.org/repository/macports/contrib/mpvim/ vim] * [https://github.com/judaew/macports.nvim Neovim] == Checksum tips == === Checksums for port updates === If you're updating a port's version and simply need the checksums for the new version, run the following while in the port's directory: {{{ $ port -v checksum ... The correct checksum line may be: checksums md5 1ca0cf40350913fa620f73cbd906378a \ sha1 2921531ece0eacb303b0c9a4978d0d050dcfd5d2 \ rmd160 6cacbcf37581b5e19fe9fe674dd7b0722f1a19de }}} You can then copy/paste the result into the Portfile. You should probably then manually tweak the whitespace of these lines to match the existing whitespace of the portfile to keep things consistent. === A bash script for checksums === {{{ #!sh #!/bin/bash if [ -f "$1" ]; then basename $1 | sed -e "s/\(.*\)/\1 \\\/" md5 $1 | sed -e "s/^MD5.*=/md5/" | sed -e "s/\(.*\)/\1 \\\/" openssl sha1 $1 | sed -e "s/^SHA1.*=/sha1/" | sed -e "s/\(.*\)/\1 \\\/" openssl rmd160 $1 | sed -e "s/^R.*=/rmd160/" fi }}} For example, assume this is in ~/bin/macports_checksum.bash, then we get: {{{ $ macports_checksum.bash ~/Downloads/libpqxx-3.0.1.tar.gz libpqxx-3.0.1.tar.gz \ md5 23557f306821bf4cae39cca45acdf9e1 \ sha1 a37874511946ba340d5df2d92252177f9eb906f6 \ rmd160 1f842ea95ad6dd2cba2cdc2d2bd8e0be5063fb9b }}} == Testing Port Phases == Individual port phases (fetch, checksum, extract, patch, configure, build, destroot, install and activate; see [http://guide.macports.org/#reference.phases phases]) can be run by using the appropriate keyword, e.g.: {{{ port extract python26 port patch python26 port build python26 }}} All phases that have not already been performed up to the designated phase will be run. If you want to rerun a port command that completed successfully, you can edit ./work/.macports.[port name].state and remove the lines up to the completed stage you want to keep. By default, if the portfile is changed, you will get the message: {{{ Portfile changed since last build; discarding previous state. }}} and the build directory will be removed (cleaned) before proceeding. When debugging a portfile, this can be avoided by using the '-o' flag (from the manpage): {{{ -o honor state files older than Portfile }}} == Searching for ports of a specific maintainer == To find ports maintained by a particular maintainer, you can use the "maintainer:" pseudoport. Maintainers can list their email address in a port in [http://guide.macports.org/#reference.keywords.maintainers several different ways], and you must search for all of them to be sure you find all relevant ports. For example, to print the name and maintainer(s) of all ports maintained by julesverne: {{{ HANDLE=julesverne port info --name --maintainer '(' \ "maintainer:(\s|^)$HANDLE(\s|$)" or \ "maintainer:(\s|^)$HANDLE@macports.org(\s|$)" or \ "maintainer:(\s|^)macports.org:$HANDLE(\s|$)" ')' }}} which will now find only those ports which !HANDLE@macports.org maintains.