Scripts

The abjad/scr/devel directory contains scripts for Abjad developers. Add abjad/scr/devel to your PATH to use the scripts described below.

abjad$ ls scr/devel
abj-grep           abj-rmpycs         count-source-lines
abj-grp            abj-update         replace-in-files

Searching the Abjad codebase with abj-grep

Abjad provides a wrapper around UNIX grep in the form of abj-grep. Use this script to recursively search the entire Abjad codebase, leaving out non-human-readable files, files located in special .svn Subversion subdirectories, and all files in the abjad/documentation directories. You can run abj-grep from any directory on your system; you needn’t be in the Abjad source directories when you call abj-grep.

$ abj-grep 'is_assignable('

leaf/duration.py:111:         if not durtools.is_assignable(rational):
tempo/indication.py:67:         assert durtools.is_assignable(arg)
tools/check/are_scalable.py:12:         if not durtools.is_assignable(candidate_duration):
tools/durtools/is_assignable.py:5:def is_assignable(duration):
tools/durtools/prolated_to_written.py:2:from abjad.tools.durtools.is_assignable import is_assignable
tools/durtools/prolated_to_written.py:15:   if is_assignable(prolated_duration):
tools/tietools/duration_change.py:28:   if durtools.is_assignable(new_written_duration):
tools/tuplettools/contents_scale.py:30:   if durtools.is_assignable(multiplier):

Removing old *.pyc files with abj-rmpycs

See the section on abj-update below for the reasons that it is a good idea to periodically remove the byte-compiled *.pyc files that Python generates for its own use behind the scenes. Abjad supplies abj-rmpycs to delete all the *.pyc in the Abjad codebase, leaving other *.pyc on your system untouched.

Updating your development copy of Abjad with abj-update

The normal way of updating your working copy of a Subversion repository is with the svn update or svn up command. You can update your working copy of Abjad in the usual way with svn up. But Abjad supplies an abj-update script as a wrapper around the usual Subversion update commands. In addition to updating your working copy of Abjad, abj-update populates the abjad/.version file with the most recent revision number of the system, and then removes all *.pyc files from your Abjad install. The benefits here are twofold. First, Abjad adds the most recent revision number of the system to all .ly files that you generate when working with Abjad. If you do not update the Abjad version file on a regular basis, the headers in your Abjad-generated .ly files will list the wrong version of the system. Second, as is the case in working with any substantial Python codebase, it is a good idea to periodically remove the byte-compiled *.pyc files that Python creates for its own use. The reason for this is inadvertant name aliasing. That is, if there was previously a module named foo.py somewhere in the system and if Python had at some point imported the module and created foo.pyc as a byprodct, this .pyc file will remain on the filesystem even if you later decide to remove, or rename, the source foo.py module. This lead to confusion because days or weeks after foo.py has been removed, Python will still find foo.pyc and seem to make the contents of foo.py available from beyond the grave. Updating with abj-update takes care of these two situations.

Counting lines of code with count-source-lines

Run count-source-lines for a count of lines of count divided between source and test files.

abjad$ count-source-lines

source_modules: 713
test_modules: 580

source_lines: 25899
test_lines: 46111

total lines: 72010
test-to-source ratio is 1.8 : 1

The script is directory-dependent so you can run it any the entire Abjad codebase or any subdirectory of the codebase.

Global search-and-replace with replace-in-files

You probably won’t need to use replace-in-files very often. But if you are making changes to Abjad that will cause some name, such as FooBar, to be globally changed everywhere in the Abjad codebase to, say to foo_bar, then you can use replace-in-files to save lots of time.

$ replace-in-files --help

     Usage:

     replace-in-files DIR OLD_TEXT NEW_TEXT [CONFIRM=true/false]

     Crawl directory DIR and read every file in it recursively.
     Replace OLD_TEXT with NEW_TEXT in each file.

     Set CONFIRM to `false` to replace without prompting.

Adding new development scripts

If you write and then find yourself using a certain script over and over again when you’re developing new code for Abjad, consider contributing back to the project so we can include your script in the next public release of Abjad. Scripts in the the Abjad script directories end with no file extension and try to be as OS-portable as possible, which usually means writing the script in Python, rather than your operating system’s shell, and relying heavily on Python’s os module.