Svnman
Svnman (pronounced ess-vee-en-man) is the ProgClub Subversion project administration software. That's the software that manages creation, maintenance, and release of Subversion projects. Svnman also supports recursive 'svn:externals' pinning with its freeze and unfreeze features. Svnman is primarily concerned with managing the version numbers for projects and releases thereof, and also the content of "branches", "tags", and "trunk" in your Subversion projects. For other projects see projects.
Status
We use semantic versioning. Latest production version: 1.0. Latest development version: 1.0.
See TODO for work that still needs to be done.
Motivation
Why this software? Basically to help with project administration of Subversion projects, particularly around versioning of artefacts.
Some particular pain points which resulted in the development of svnman were wanting to:
- have a sensible, robust, comprehensive, and well considered version numbering strategy which could be applied to all our projects
- have a managed PATCH version number which got incremented automatically upon each change to the project (for example prior to every Subversion check-in)
- support development on version branches to facilitate maintenance of older versions while newer versions are under development or in the pipeline
- keep 'trunk' tracking the latest stable release while doing development on version branches
- and also to keep a bunch of standard 'tags' up-to-date
- have a standard project layout created for each new project
- with extra special support for our PHPBOM library
- and also support for automatic NetBeans project creation
- manage multiple versions of multiple projects in multiple repositories, and have them integrate sensibly with each other
- have standard locations for project code generation, testing, and release scripts
- be able to freeze a project prior to (or during) release and then unfreeze it after
- this enables a very agile practice whereby we can edit our dependencies in-place but release them safely too
Demonstration
Here we have a quick intro (3 A4 pages) and a more detailed walk through (6 A4 pages).
Quick intro
This quick intro demonstrates the value of svnman by taking you through some project administration basics. This intro has no prerequisites and all changes are done under the /tmp directory so you can follow along on your own computer (assuming you're running a sensible version of GNU/Linux, such as Ubuntu or Debian). To get set up:
$ sudo apt install php-cli subversion
Then get a copy of the code:
$ svn checkout https://www.progclub.org/svn/pcrepo/svnman/trunk /tmp/svnman
And create an alias for access:
$ alias svnman='/usr/bin/env php /tmp/svnman/bin/svnman.php'
Then create a demo repository for testing purposes:
$ svnadmin create /tmp/demorepo
You can then configure a 'demorepo' repository alias with the config subcommand. A repository alias allows you to refer to repository location, working base directory, and other settings, with an alias that has those details associated with it. For example to configure a 'demorepo' alias for our demo Subversion repository and working base directory:
$ svnman config --alias demorepo --location file:///tmp/demorepo --working-base /tmp
Note that the working base directory is the parent directory of our working copies. So we're just gonna put our working copies in /tmp
for this demo.
Now you can create a new project named 'svnman-demo' in the 'demorepo' repository like this:
$ svnman create --repo demorepo --project svnman-demo
All new projects start at v0.1. A version branch of your new project has been checked out into a working copy at /tmp/svnman-demo-0.1
, so go there:
$ cd /tmp/svnman-demo-0.1
The version branch is where software development is done. By default you will see that a bunch of default project files (and directories) have been created for you:
jj5@tact:/tmp/svnman-demo-0.1$ ls
bin doc etc ext inc lib src
We'll add a test file to our project and then release v0.1, like this:
jj5@tact:/tmp/svnman-demo-0.1$echo demo > file.txt
jj5@tact:/tmp/svnman-demo-0.1$svn add file.txt
jj5@tact:/tmp/svnman-demo-0.1$svnman commit
jj5@tact:/tmp/svnman-demo-0.1$svnman release
The output indicates that v0.1.4 has been released:
Latest...: file:///tmp/demorepo/svnman-demo/tags/latest/0.1 Major....: file:///tmp/demorepo/svnman-demo/tags/major/0 Minor....: file:///tmp/demorepo/svnman-demo/tags/minor/0/1 Release..: file:///tmp/demorepo/svnman-demo/tags/release/0/1/4 Trunk....: file:///tmp/demorepo/svnman-demo/trunk
So after our release our 'trunk' is now at version 0.1.4. You can confirm this by looking at the version file in trunk:
$ svn cat file:///tmp/demorepo/svnman-demo/trunk/inc/version.php
<?php // the version numbers are managed by svnman... define( 'SVNMAN_DEMO_VERSION_MAJOR', 0 ); define( 'SVNMAN_DEMO_VERSION_MINOR', 1 ); define( 'SVNMAN_DEMO_VERSION_PATCH', 4 ); // you can change the name but not the code... define( 'SVNMAN_DEMO_NAME', 'svnman-demo' ); define( 'SVNMAN_DEMO_CODE', 'svnman-demo' ); // the following are automatically updated by Suybversion... define( 'SVNMAN_DEMO_SVN_DATE', '$Date: 2020-03-08 12:50:38 +1100 (Sun, 08 Mar 2020) $' ); define( 'SVNMAN_DEMO_SVN_REVISION', '$Revision: 6 $' ); define( 'SVNMAN_DEMO_SVN_AUTHOR', '$Author: jj5 $' );
Let's checkout our trunk, like this:
$ svn co file:///tmp/demorepo/svnman-demo/trunk /tmp/svnman-demo-trunk
You can see our test file 'file.txt' is in trunk:
$ ls /tmp/svnman-demo-trunk
bin doc etc ext file.txt inc lib src
Now let's bump our minor version and start v0.2 of our demo project:
jj5@tact:/tmp/svnman-demo-0.1$ svnman bump-minor
A version branch of your new project has been checked out into a working copy at '/tmp/svnman-demo-0.2', so go there:
$ cd /tmp/svnman-demo-0.2
Now for v0.2 let's remove file.txt then release:
jj5@tact:/tmp/svnman-demo-0.2$svn rm file.txt
jj5@tact:/tmp/svnman-demo-0.2$svnman commit
jj5@tact:/tmp/svnman-demo-0.2$svnman release
Now let's go back to our trunk and get the latest version:
$cd /tmp/svnman-demo-trunk
$svn update
$ls
bin doc etc ext inc lib src
You will see that 'file.txt' has been removed from trunk. But note that we didn't do any development on trunk. We did our development on the v0.1 version branch, then the v0.2 version branch, and trunk (and some tags and version numbers) were managed for us automatically by svnman. Managing the version numbers and the project in the Subversion repository is what svnman does!
So during this quick intro we created a 'demorepo' repository, then added a 'svnman-demo' project, and released two versions of our project, v0.1 and v0.2. You can see our effect with the list subcommand:
$ svnman list --repo demorepo
* svnman-demo: [0.1], [0.2]: file:///tmp/demorepo/svnman-demo/branches
And that concludes our quick intro. To clean up after yourself please run:
$ cd / && rm -rf /tmp/{demorepo,svnman*} && unalias svnman
If you like what you see you can install a permanent copy of svnman by following the instructions in the Installation Guide.
Walk through
This walk through demonstrates the value of svnman by taking you through the whole project administration life cycle from configuration to creation to maintenance to release to the next versions. This walk through has no prerequisites and all changes are done under the /tmp directory so you can follow along on your own computer (assuming you're running a sensible version of GNU/Linux, such as Ubuntu or Debian). To get set up:
$ sudo apt install php-cli subversion
Then get a copy of the code:
$ svn checkout https://www.progclub.org/svn/pcrepo/svnman/trunk /tmp/svnman
And create an alias for access:
$ alias svnman='/usr/bin/env php /tmp/svnman/bin/svnman.php'
Then create a demo repository for testing purposes:
$ svnadmin create /tmp/demorepo
You can then configure a 'demorepo' repository alias with the config subcommand. A repository alias allows you to refer to repository location, working base directory, and other settings, with an alias that has those details associated with it. For example to configure a 'demorepo' alias for our demo Subversion repository and working base directory:
jj5@tact:/tmp$ svnman config --alias demorepo --location file:///tmp/demorepo --working-base /tmp
Note that the working base directory is the parent directory of our working copies. So we're just gonna put our working copies in '/tmp' for this demo.
Now you can create a new project named 'svnman-demo' in the 'demorepo' repository like this:
jj5@tact:/tmp$ svnman create --repo demorepo --project svnman-demo
The output will be something like this:
/tmp/svnman-demo-0.1
which indicates that v0.1 (all new projects start at version 0.1) of your new project has been checked out into '/tmp/svnman-demo-0.1', so go there:
jj5@tact:/tmp$ cd /tmp/svnman-demo-0.1
Let's create a test program, like this:
jj5@tact:/tmp/svnman-demo-0.1$echo $'#!/usr/bin/env php\n<?php echo "hello, world.\n";' > bin/hello.php
jj5@tact:/tmp/svnman-demo-0.1$chmod +x bin/hello.php
jj5@tact:/tmp/svnman-demo-0.1$svn add bin/hello.php
You can then commit with svnman. Committing with svnman ensures that code maintenance is run prior to checkin. Maintenance involves an optional code generation step and then the increment of the PATCH version number. By default the version numbers are in 'inc/version.php'. Run the following commands to see the SVNMAN_DEMO_VERSION_PATCH version incremented from 1 to 3:
jj5@tact:/tmp/svnman-demo-0.1$cat inc/version.php
jj5@tact:/tmp/svnman-demo-0.1$svnman commit -m 'Commit messages are optional.'
jj5@tact:/tmp/svnman-demo-0.1$cat inc/version.php
If you're happy with v0.1 you can release it:
jj5@tact:/tmp/svnman-demo-0.1$ svnman release
The release process created the following tags in our Subversion repository (and also updated trunk):
Latest...: file:///tmp/demorepo/svnman-demo/tags/latest/0.1 Major....: file:///tmp/demorepo/svnman-demo/tags/major/0 Minor....: file:///tmp/demorepo/svnman-demo/tags/minor/0/1 Release..: file:///tmp/demorepo/svnman-demo/tags/release/0/1/4 Trunk....: file:///tmp/demorepo/svnman-demo/trunk
You can use svn ls
to inspect, e.g.:
jj5@tact:/tmp/svnman-demo-0.1$ svn ls file:///tmp/demorepo/svnman-demo/trunk
You can see the version config file for your release here:
jj5@tact:/tmp/svnman-demo-0.1$ svn cat file:///tmp/demorepo/svnman-demo/trunk/inc/version.php
Note that for your production release in 'trunk' the SVNMAN_DEMO_VERSION_PATCH version is 4. Your development branch is at PATCH = 5, see:
jj5@tact:/tmp/svnman-demo-0.1$ cat inc/version.php
Maintaining that PATCH version number — and making sure it is regularly and consistently updated — is perhaps the main job of svnman. See the versioning section for details, but basically an even PATCH version is for a PROD (for "production") build, and an odd PATCH version is for a DEV (for "development") build. The release process makes sure the PATCH version number is properly incremented during each stage of a release.
So now that v0.1 is released, it's time to get ready for development of v0.2 with bump-minor. The bump-minor subcommand will increment the MINOR version number from 1 to 2:
jj5@tact:/tmp/svnman-demo-0.1$ svnman bump-minor
The output will be something like this:
/tmp/svnman-demo-0.2
which indicates that your new project version has been checked out into '/tmp/svnman-demo-0.2', so go there:
jj5@tact:/tmp/svnman-demo-0.1$ cd /tmp/svnman-demo-0.2
In order to test freezing/unfreezing of 'svn:externals' when we run our release (below) we need to set up an extra project we can use as a library:
jj5@tact:/tmp/svnman-demo-0.2$ svnman create --repo demorepo --project svnman-demo-lib
Now for v0.2 let's include our library project as an external project:
jj5@tact:/tmp/svnman-demo-0.2$ svn propset svn:externals "svnman-demo-lib file:///tmp/demorepo/svnman-demo-lib/branches/0.1" ext
And commit our changes:
jj5@tact:/tmp/svnman-demo-0.2$ svnman commit
Now if you do an `svn update` you will get a copy of svnman-demo-lib in the 'ext' dir:
jj5@tact:/tmp/svnman-demo-0.2$svn update
jj5@tact:/tmp/svnman-demo-0.2$ls ext/
Now let's change our program a little bit for v0.2:
jj5@tact:/tmp/svnman-demo-0.2$ echo $'#!/usr/bin/env php\n<?php echo "hello from v0.2!\n";' > bin/hello.php
And commit our changes:
jj5@tact:/tmp/svnman-demo-0.2$ svnman commit
So v0.2 looks fairly good, let's release it:
jj5@tact:/tmp/svnman-demo-0.2$ svnman release
As before the release process created a bunch of tags in our Subversion repository (and updated trunk):
Latest...: file:///tmp/demorepo/svnman-demo/tags/latest/0.2 Major....: file:///tmp/demorepo/svnman-demo/tags/major/0 Minor....: file:///tmp/demorepo/svnman-demo/tags/minor/0/2 Release..: file:///tmp/demorepo/svnman-demo/tags/release/0/2/12 Trunk....: file:///tmp/demorepo/svnman-demo/trunk
So we're done with v0.2, let's get ready for our v1.0 release with bump-major. The bump-major command will increment the MAJOR version number from 0 to 1:
jj5@tact:/tmp/svnman-demo-0.2$ svnman bump-major
The output will be something like this:
/tmp/svnman-demo-1.0
which indicates that your new project version has been checked out into '/tmp/svnman-demo-1.0', so go there:
jj5@tact:/tmp/svnman-demo-0.2$ cd /tmp/svnman-demo-1.0
Again we can modify our program for v1.0:
jj5@tact:/tmp/svnman-demo-1.0$ echo $'#!/usr/bin/env php\n<?php echo "hello from v1.0!\n";' > bin/hello.php
And commit:
jj5@tact:/tmp/svnman-demo-1.0$ svnman commit
And release:
jj5@tact:/tmp/svnman-demo-1.0$ svnman release
And now v1.0 is in production:
Latest...: file:///tmp/demorepo/svnman-demo/tags/latest/1.0 Major....: file:///tmp/demorepo/svnman-demo/tags/major/1 Minor....: file:///tmp/demorepo/svnman-demo/tags/minor/1/0 Release..: file:///tmp/demorepo/svnman-demo/tags/release/1/0/18 Trunk....: file:///tmp/demorepo/svnman-demo/trunk
You can look at the version file to see the MAJOR.MINOR.PATCH version numbers which are now at v1.0.19:
jj5@tact:/tmp/svnman-demo-1.0$ cat inc/version.php
Example output:
<?php // the version numbers are managed by svnman... define( 'SVNMAN_DEMO_VERSION_MAJOR', 1 ); define( 'SVNMAN_DEMO_VERSION_MINOR', 0 ); define( 'SVNMAN_DEMO_VERSION_PATCH', 19 ); // you can change the name but not the code... define( 'SVNMAN_DEMO_NAME', 'svnman-demo' ); define( 'SVNMAN_DEMO_CODE', 'svnman-demo' ); // the following are automatically updated by Suybversion... define( 'SVNMAN_DEMO_SVN_DATE', '$Date: 2020-03-08 15:20:27 +1100 (Sun, 08 Mar 2020) $' ); define( 'SVNMAN_DEMO_SVN_REVISION', '$Revision: 44 $' ); define( 'SVNMAN_DEMO_SVN_AUTHOR', '$Author: jj5 $' );
And have a look at the 'svn:externals' on the release tag for our v1.0 release:
jj5@tact:/tmp/svnman-demo-1.0$ svn propget svn:externals file:///tmp/demorepo/svnman-demo/tags/latest/1.0/ext
The output will be something like this:
svnman-demo-lib -r35 file:///tmp/demorepo/svnman-demo-lib/branches/0.1
Compare that with the development version from the 1.0 version branch:
jj5@tact:/tmp/svnman-demo-1.0$ svn propget svn:externals file:///tmp/demorepo/svnman-demo/branches/1.0/ext
The output will be something like this:
svnman-demo-lib file:///tmp/demorepo/svnman-demo-lib/branches/0.1
Notice that for the tagged release the 'svn:externals' have been "frozen" on revision 35 (-r35), whereas for the development version on the version branch the externals definition is not pinned to a specific revision but is tracking HEAD. That's a consequence of the freeze and unfreeze processes which happen automatically before and after a release. Freezing and unfreezing of 'svn:externals' before creating release tags is another main reason for using svnman.
So during this walk through we created a 'demorepo' repository, then added multiple versions of two projects ('svnman-demo' and 'svnman-demo-lib'). You can see our effect with the list subcommand:
$ svnman list --repo demorepo
* svnman-demo: [0.1], [0.2], [1.0]: file:///tmp/demorepo/svnman-demo/branches * svnman-demo-lib: [0.1]: file:///tmp/demorepo/svnman-demo-lib/branches
And that concludes our walk through. To clean up after yourself please run:
$ cd ~ && rm -rf /tmp/demorepo /tmp/svnman* && unalias svnman
If you like what you see please see the Installation Guide for help with configuring svnman in production.
Administration
Contributors
Members who have contributed to this project. Newest on top.
All contributors have agreed to the terms of the Contributor License Agreement. This excludes any upstream contributors who tend to have different administrative frameworks.
Copyright
Copyright © 2020, Contributors.
License
Licensed under the MIT license.
Components
Libraries, tools, services or media from third parties used under license:
Resources
Downloads
There are presently no tarballs. Running an `svn checkout` against the ProgClub Subversion repository (pcrepo) is the recommended way to install this software. See the Installation Guide for details.
Source code
The source code can be browsed online:
The most interesting code is here:
The latest stable (read-only) released version of the code is available from Subversion here:
Or if you want the latest version for development purposes:
Note that our software development is done on the version branch, not on trunk. We use trunk to track the latest stable release.
Reference
The command reference contains a cheatsheet for frequently used commands. The repository command reference has a reference implementation for custom per-repository commands.
Command reference
Here are some basic notes on svnman commands which you might use frequently. Note that all of these commands rely on the 'inc/shell.sh' file being sourced in your shell. See shell configuration if you need help with that. Note that rarely will you invoke the `svnman` command directly, usually you will use one of these wrapper commands:
Command | Notes | Changes directory? |
---|---|---|
sx | `svn update && svn status` | no |
ss | `svn update && svn status --ignore-externals` | no |
sva | `svn add --force --auto-props --parents --depth infinity .` | no |
sci | `svnman sync` | no |
release | `svnman release` (or bin/dev/release.sh) | no |
bump-minor | `svnman bump-minor` | yes |
bump-major | `svnman bump-major` | yes |
svnman-create | `svnman create --repo $1 --project $2 ...` | yes |
svnman-list | `svnman list --repo $1 ...` | no |
svnman-checkout | `svnman checkout --repo $1 --project $2 ...` | yes |
Repository command reference
Here are some custom commands for use directly against the ProgClub Subversion repository, pcrepo:
Command | Notes | Changes directory? |
---|---|---|
pcrepo | `pushd ~/repo/svn/pcrepo` | yes |
pcrepo-config | `svnman config --alias pcrepo ...` | no |
pcrepo-create | `svnman-create pcrepo "$@"` | yes |
pcrepo-list | `svnman-list pcrepo "$@"` | no |
pcrepo-checkout | `svnman-checkout pcrepo "$@"` | yes |
You are encouraged to use the 'pcrepo' reference implementation to create your own custom repository commands. You can find the reference implementation for the 'pcrepo' functions at the bottom of the 'inc/shell.sh' script.
Specifications
Functional specification
The functional specification describes what the project does.
svnman
The svnman software provides a system command called `svnman` which has various subcommands for administering projects in a Subversion repository.
The `svnman` command is usually established by creating a symlink somewhere in your $PATH to point at the 'bin/svnman.php' script that comes with the project source code. See the Installation Guide for information about how to set up an `svnman` command in your environment.
For details concerning the features available from the `svnman` command please see the command-line interface.
Subversion replacements
The svnman software augments some of your Subversion processes. In the large you can go on using Subversion like you used to, with e.g. `svn add`, `svn rm`, `svn diff`, etc. But there are a few `svn` subcommands that you should no longer use directly, instead you should use the corresponding/replacement svnman functionality instead. Those `svn` subcommands which are replaced are:
- svn checkout (co)
- svn status (stat, st)
- svn commit (ci)
svn checkout
You can actually continue to use `svn checkout` directly, if you'd like; but there is an 'svnman-checkout' shell function which might make your life easier, as it automatically determines a project's latest version and will `cd` to your working copy on completion.
So svn checkout https://www.progclub.org/svn/pcrepo/svnman/branches/1.0/ svnman-1.0 && cd svnman-1.0
can be replaced with svnman-checkout pcrepo svnman
.
svn status
You can still run `svn status` if you want, but we have a command, 'ss' (short for 'svn status'), which will do an `svn update` before an `svn status`. You can use 'ss' to make sure you're up to date and to check if you have any uncommitted changes.
So svn update && svn status
can be replaced with ss
.
In addition to the 'ss' is the 'sx' command which is similar to 'ss' but includes svn:externals.
svn commit
If you're working on a Subversion project that is managed by svnman then you probably shouldn't use `svn commit` (AKA `svn ci`) anymore.
The `svn commit` replacement is the command 'sci' (short for 'svn check-in') which you should call to commit changes in your working copy. (If you're not sure if you have changes, run 'ss'.)
If you are going to use `svn commit` directly (and you really shouldn't), please at least make sure that you call `svnman maint` before doing your commit.
Shell integration
The svnman software has been designed for maximal integration with your Unix shell, particularly BASH. We recommend adding the svnman aliases and shell functions to your .bashrc (or similar) — see the shell configuration section for details. These functions provide a simpler command-line interface to svnman and their output is used to change directory upon completion, which is quite handy.
Most of these aliases and shell functions are supposed to run with the current working directory pointing to a Subversion working copy.
So for example the PHPBOM project would have been created like this:
$ pcrepo-create phpbom
Note that these functions assume you have configured appropriate repository aliases (such as 'pcrepo') for use with the --repo argument.
The following aliases and shell functions (and some extra bonus stuff) are available for download from the svnman source, see the 'inc/shell.sh' script for details. You should source this script from your '.bashrc' file, or similar.
sx command
The 'sx' command is short for 'svn status'. It is similar to the ss command but this command includes svn:externals. It simply does an `svn update` followed by an `svn status`. We recommend you use 'sx' in place of 'svn status'. Running this command a lot is a good idea, because generally you want your working copy to be as fresh as it can be.
ss command
The 'ss' command is short for 'svn status --ignore-externals'. It is similar to the sx command but this command ignores svn:externals. It simply does an `svn update` followed by an `svn status --ignore-externals`. We recommend you use 'ss' in place of 'svn status'. Running this command a lot is a good idea, because generally you want your working copy to be as fresh as it can be.
sva command
The 'sva' command is short for 'svn add'. It automatically flags all unversioned files for addition.
sci command
The 'sci' command is short for 'svn check-in'. It's a shortcut for `svnman sync`, which will make sure you're up to date and then commit changes, if any, after having run maintenance.
release command
The 'release' command is a shortcut for `svnman release`, or, alternatively, a custom project release script: 'bin/dev/release.sh'.
bump-minor command
The 'bump-minor' command is a shortcut for `svnman bump-minor'. It operates on the current working directory and will `cd` to the working copy of the new project version upon completion.
bump-major command
The 'bump-major' command is a shortcut for `svnman bump-major'. It operates on the current working directory and will `cd` to the working copy of the new project version upon completion.
svnman-create command
The 'svnman-create' command is a shortcut for `svnman create`. It's first argument is a repo alias and the second argument is a project name.
svnman-list command
The 'svnman-list' command is a shortcut for `svnman list`. It's first argument is a repo alias.
svnman-checkout command
The 'svnman-checkout' command is a shortcut for `svnman checkout`. It's first argument is a repo alias and the second argument is a project name.
Repository commands
It can be useful to create some custom shell functions to operate directly on your various repositories. Our 'inc/shell.sh' script has some example functions for pcrepo, being:
- pcrepo
- pcrepo-config
- pcrepo-create
- pcrepo-list
- pcrepo-checkout
As a convenience you can create the analogous shell functions for your own repositories.
Technical specification
The technical specification describes how the project works.
The software is written in PHP (tested on version 7.2) and shells out to the `svn` command-line utility (tested on version 1.9.7).
Configuration data is kept in JSON format in '$HOME/.config/svnman/config.json'. Use the `svnman config` subcommand to specify configuration data via the command-line.
Versioning
The versioning article goes into more detail, but basically the version numbers supported by svnman are in the format MAJOR.MINOR.PATCH. Note that this versioning standard is used by both the svnman software itself and also any projects which use svnman as their project administration tool. This versioning standard is the only versioning standard supported by svnman at the present time.
Note that there can be multiple MAJOR.MINOR releases whereas a specific MAJOR.MINOR.PATCH release is unique. This means that you can continue issuing patches (such as security updates) to particular MAJOR.MINOR versions and releasing them while work is under way on newer MAJOR.MINOR versions. If you need a new MAJOR.MINOR version (say for your next prospective production release) then see the bump-minor subcommand for help with that. If you're getting ready for a new MAJOR version (which you should definitely consider if you're planning to introduce breaking changes) then see bump-major.
The versioning specification has support for extra version info, but that is not relevant to svnman, and svnman can be used with or without that extra information. Actually the introduction of the capabilities of svnman, particularly around management of the PATCH version number, have made some of that extra version information less important than it used to be (i.e. we don't need to lean on Subversion revision numbers to identify a version).
MAJOR
The MAJOR version number is the first number in a version and is incremented for breaking changes, except for version zero (0) and version one (1) which may be unstable.
MINOR
The MINOR version number is the second number in a version and is incremented for non-breaking changes for new supported versions. It starts at one (1) for MAJOR version zero (0), and at zero (0) for successive MAJOR versions. If you want to work on a new version of your project while having the capacity to maintain the previous version then you should bump the MINOR version prior to starting the new work.
PATCH
The PATCH version number is the third number in a version and is incremented prior to every commit (and release); the PATCH is odd for DEV builds and even for PROD builds. Note that not all PATCH versions get released.
Builds
Only two types of builds are supported by svnman: DEV and PROD. If you want to cut a BETA or Release Candidate (RC1, RC2, etc.) build, you can do that (see the versioning article for help on this topic), but it's best to use a DEV build for those, saving PROD for real live actual supported versions. When you run a release with the `svnman release` subcommand a PROD build is configured for release. After the production release the project is reconfigured as the next DEV build. So PROD builds only exist during a release, and before and after a release the project is for a DEV build. In this way all releases are releases to PROD, that's what 'release' means.
DEV
A 'DEV' (for "development") build is for a programmer or tester for testing and development purposes. You can use a DEV build in production if you want, but it might have known errors, change rapidly, or otherwise be unsupported. You can tell DEV builds by their odd PATCH version number (PATCH % 2 == 1). If you track the version branch you will typically see a DEV build, except for temporarily during an `svnman release`.
PROD
A 'PROD' (for "production") build is created by a project administrator (using the `svnman release` subcommand) when testing of the version branch is complete. You can tell PROD builds by their even PATCH version number (PATCH % 2 == 0). During a release PROD builds get tagged with their MAJOR.MINOR version number under 'tags/latest/' and also with their MAJOR/MINOR/PATCH version number under 'tags/release/'. Usually when the latest version branch is released to PROD we update 'trunk' to point at it. In this way 'trunk' usually tracks the latest stable production version, which might be different to what you're used to. If you track 'trunk' or 'tags' you should only ever see PROD builds, as DEV builds only happen on the version branch.
Repository layout
This section documents the layout of the project root and everything below it for projects stored in a Subversion repository.
Project root
The project root is a location in a Subversion repository named for the project. It can be the repository root, but is more usually a directory with a project name. For instance the project root for the svnman software in our pcrepo Subversion repository is:
The svnman software only supports project roots named after the project and stored directly within the repository. So if the project is called 'svnman' and the repository is 'https://www.progclub.org/pcrepo' then the project root is 'https://www.progclub.org/pcrepo/svnman'.
Topmost directories
When trying to figure out what to call everything I reviewed the svnbook, particularly the Recommended Repository Layout section. But that document simply referred to the subdirectories of the "topmost" directory, the "topmost" directory being the "project root". So I've just called the branches, tags, and trunk directories "topmost" directories, as that is where they are found. A name was needed for the --topmost argument, and also, I guess, for this documentation. So there is the project root (named after the project), then the "topmost directories", being branches, tags, and trunk, and then under those things start to vary based on the various types, the details follow.
So svnman presumes that the Subversion project has these "topmost" directories within the project root:
And that is fairly standard for a Subversion project. However, we don't use 'trunk' for development. Instead development happens in MAJOR.MINOR version branches.
When a version branch is released by svnman 'trunk' can optionally be updated. Within 'tags' the latest MAJOR.MINOR versions are maintained under 'tags/latest/MAJOR.MINOR' and releases are tagged under 'tags/release/MAJOR/MINOR/PATCH'. There are other types of tags too.
branches
So "branches" are a place for work in progress. Developers can spin up custom branches if they need, but generally work is done directly on a version branch. A version branch is a directory within "branches" named after the MAJOR.MINOR version as detailed below.
Version branches
Our software projects start with a version branch, being for version 0.1, and incrementing from there. All software development is generally done in a version branch. Version branches are project branches (under the "branches" directory in the Subversion repository) with a directory name in the format 'MAJOR.MINOR'. It's possible to have other sorts of branches (svnman will ignore those) but the branches that svnman does operate on must be version branches in the valid format.
So version 0.3 is developed in 'branches/0.3' and version 1.0 is developed in 'branches/1.0'.
For example the version branch for v1.0 of the svnman software is:
Or for a list of version branches see here:
Note that what we call "version branches" might also be called "release branches" by other people in other contexts. For us a "release" has different connotations so we talk about "version branches" not "release branches". Generally we don't use "feature branches", we do our work directly on a "version branch", and use feature flags when necessary.
tags
Once development on a version branch is stable, tested, and ready for release, the `svnman release` process is run. The release process creates and updates:
- tags/major/MAJOR
- tags/minor/MAJOR/MINOR
- tags/release/MAJOR/MINOR/PATCH (which is an immutable tag for the release)
- tags/latest/MAJOR.MINOR
- trunk (only updated for releases of the latest released MAJOR.MINOR version)
The astute reader will note that 'tags/minor' and 'tags/latest' are very similar, in that they both track MAJOR.MINOR versions, but in different ways. Both are supported and maintained, so which one you use is up to you. Having the two formats is useful for consistency with the 'tags/major' format but also the utility of having all MAJOR.MINOR releases available for review under 'tags/latest'.
tags/major
A 'tags/major' tag tracks the latest version for a MAJOR version number.
An example 'tags/major' for v1.x is here:
Following a MAJOR version tag instead of trunk is a solid choice. However, please note that per our versioning standard stability of MAJOR versions is not supported until version two (2).
tags/minor
A 'tags/minor' tag tracks the latest version for a MAJOR.MINOR version number.
An example 'tags/minor' for v1.0 is here:
tags/release
A 'tags/release' tag tracks a release for a MAJOR.MINOR.PATCH version number. Note that these tags are immutable. Unlike other tags the 'tags/release' tags are never altered after they have been created.
An example 'tags/release' for v1.0.1276 is here:
tags/latest
The 'tags/latest' tag tracks the latest version for a MAJOR.MINOR version number, but in a different format to 'tags/minor'.
An example 'tags/latest' for v1.0 is here:
Or for a list of released MAJOR.MINOR versions see here:
trunk
The absolute latest stable released version is always in trunk. Note that if older versions are maintained and released they won't override trunk. Trunk tracks the latest release of the latest MAJOR.MINOR version, and you can rely on 'trunk' to always have the latest released version. But be warned: if you follow 'trunk' you may get upgraded across MAJOR version numbers, which may have breaking changes. If that is of concern to you then you might prefer to track the MAJOR version in 'tags/major'.
An example 'trunk' is here:
Project layout
So when you create new projects with `svnman create` you get a bunch of boiler plate stuff automatically created for you. (And if you use one of the --phpbom arguments you get even more scaffolding.)
A typical initial project looks like this:
- bin -- command-line programs
- dev -- command-line programs for use in development
- gen.sh -- project code generator
- release.sh -- project release script
- test -- command-line programs for testing
- test.sh -- project test script
- dev -- command-line programs for use in development
- doc -- project documentation
- gen -- automatically generated documentation
- etc -- project configuration files
- ext -- 'svn:externals' projects managed with freeze and unfreeze
- inc -- include files
- version.php -- version file
- lib -- third-party libraries
- src -- source code
bin
The 'bin' directory contains command-line programs provided with the project.
bin/dev
The 'bin/dev' directory contains command-line programs for use during software development.
bin/dev/gen.sh
The 'bin/dev/gen.sh' script is for project code generation. Compiling, compression, and minification are all things that can be done with this script. Code generation is done automatically during maintenance, but it's not a bad idea to run it again in 'bin/dev/release.sh' to make sure things are up-to-date prior to a release.
bin/dev/release.sh
The 'bin/dev/release.sh' script manages a release. By default this script just runs `svnman release` but if you need to do things before and after a release you should use this script to do those things.
bin/test
The 'bin/test' directory contains command-line programs for testing the project.
bin/test/test.sh
The 'bin/test/test.sh' script should run all tests for the project.
doc
The 'doc' directory contains project documentation.
doc/gen
The 'doc/gen' directory contains automatically generated documentation. Often code will be generated in MediaWiki format for inclusion on the project page. Documentation generation is usually done with the 'bin/dev/gen.sh' script.
etc
The 'etc' directory contains project configuration files.
etc/gen
The 'etc/gen' directory contains automatically generated configuration files. Config generation is usually done with the 'bin/dev/gen.sh' script.
etc/test
The 'etc/test' directory contains configuration files use for software testing.
ext
The 'ext' directory contains any 'svn:externals' projects that are managed with freeze, unfreeze, etc. See 'lib' for an alternative.
inc
The 'inc' directory contains include files.
inc/version.php
The 'inc/version.php' is the project version file for PHP projects. In future we may support other types of version file.
This version file is the file that gets updated with new MAJOR or MINOR or PATCH version information.
lib
The 'lib' directory contains third-party libraries used by the project. If these libraries are configured as 'svn:externals' (which is okay) they will *not* be managed by the freeze and unfreeze processes. See 'ext' for an alternative.
src
The 'src' directory contains most of the source code for a project.
src/code
The 'src/code' directory contains the main source code.
src/gen
The 'src/gen' directory contains automatically generated source code. Code generation is usually done with the 'bin/dev/gen.sh' script.
src/play
The 'src/play' directory is an area for programmers to try things out. This is for software testing purposes, but it is less formal than unit tests or integration tests etc. Programs under 'src/play' can be committed to source control but they are not run automatically during testing.
src/test
The 'src/test' directory is for unit tests and other code used during testing. See the 'bin/test/test.sh' for the main test runner.
src/tool
The 'src/tool' directory contains any tooling. Tooling is code used by code generation scripts such as 'bin/dev/gen.sh'.
src/web
The 'src/web' directory is for web content.
src/web/controller
The 'src/web/controller' directory is for front-controllers. Usually these are configured in Apache using the Alias directive to mount them at a particular URL.
src/web/res
The 'src/web/res' directory contains web assets such as styles, scripts, images, etc. This is for public web content.
src/web/root
The 'src/web/root' directory is for the content of the web root when/if this software is hosted on an entire domain. Typical files are 'favicon.ico' and 'robots.txt' etc.
Notes
Notes for implementers
If you are interested in incorporating this software into your project, here's what you need to know.
Installation
This software has been developed and tested on Ubuntu 18.04 LTS GNU/Linux. It will probably work in other Unix environments and it will definitely be broken on Windows. (If you'd like to make it work on Windows we will accept your patch!)
After you install dependencies you need to decide if you want to install for just your user or for an entire system.
Dependency installation
In order to run svnman you might also need to install some dependencies, if so do that first:
$ sudo apt install php-cli subversion
System installation
After you install dependencies you can install svnman for an entire system with these two commands:
$sudo svn checkout https://www.progclub.org/svn/pcrepo/svnman/trunk /usr/local/lib/svnman
$sudo ln -s /usr/local/lib/svnman/bin/svnman.php /usr/local/bin/svnman
Then see the shell configuration and repository configuration sections for final touches.
System upgrade
If you've done a system installation you can do a system upgrade like this:
$ sudo svn update /usr/local/lib/svnman
User installation
First make sure you've installed the dependencies.
The recommended way to install this software is by checking out the 'trunk' version from source control.
In order to run svnman you should create an 'svnman' symlink somewhere in your $PATH and point it to 'bin/svnman.php'.
So a full installation might look something like this:
$cd ~/software
$svn checkout https://www.progclub.org/svn/pcrepo/svnman/trunk svnman
$cd ~/bin
$ln -s ~/software/svnman/bin/svnman.php svnman
Then see the shell configuration and repository configuration sections for final touches.
User upgrade
Assuming you followed the user installation instructions you can do a user upgrade something like this:
$ svn update ~/software/svnman
Shell configuration
So the way to configure your shell for the best svnman experience is to edit your ~/.bashrc file and add a line to include the aliases and shell functions from the 'inc/shell.sh' script.
If you did a system installation your source line for your ~/.bashrc file will look like this:
source /usr/local/lib/svnman/inc/shell.sh
If you did a user installation your source line for your ~/.bashrc file will look something like this:
source ~/software/svnman/inc/shell.sh
So basically you need to source 'inc/shell.sh' from wherever you've stowed the svnman software.
Repository configuration
After you install svnman you might like to configure one or more repository aliases using the config subcommand.
For example the config for 'pcrepo' might be something like this:
$ svnman config \
--alias pcrepo \
--location https://www.progclub.org/svn/pcrepo \
--working-base ~/repo/svn/pcrepo \
--viewvc https://www.progclub.org/pcrepo
Notes for developers
If you're looking to set up a development environment for this project, here's what you need to know.
Get the latest code from the version branch:
$ svn checkout https://www.progclub.org/svn/pcrepo/svnman/branches/1.0 svnman-1.0
You can then run the unit tests like this:
$ cd svnman-1.0 && bin/test/test.sh
Note that you may need to install some dependencies, such as:
# apt install php-cli subversion
If you have a bugfix or improvement please send your patch to jj5@progclub.org along with a statement that you are willing to be listed in the contributors section of the documentation and that you agree to the terms of the Contributor License Agreement.
Notes for administrators
To release a version of this project use the svnman software itself.
First, from the project base directory, run maintenance and commit any changes:
$ sci
Then run the release:
$ release
You will be prompted to update the project documentation.
Miscellanea
Subversion
The svnman software makes use of the Subversion command-line interface, being the `svn` command. If Subversion is not installed then svnman won't work! You will need to know the basics of Subversion to be productive with svnman, if you need to learn the `svn` command-line the svnbook is your one stop shop. See the Subversion replacements section for notes about which `svn` subcommands you should avoid while you're using svnman for project administration.
Revisions
The Subversion software allocates a 'revision number' to each commit. The revision number starts at one (1) and increments for each successive commit. You can often use a Subversion revision number to request content that was current at the time a specific revision was made. We use revision numbers in the freeze process.
HEAD
When talking about Subversion revisions the term 'HEAD' is used to refer to the latest revision, whatever that happens to be at the time.
svn:externals
The Subversion software allows for named properties to be set on files/directories that are under source control. Some of these properties are special Subversion properties which have special meaning. One such property is the 'svn:externals' property.
The 'svn:externals' property allows for external Subversion projects to be configured as dependencies of the current project. This allows for your Subversion project to use other Subversion projects which will get loaded from their sources automatically during `svn checkout` or `svn update`. Our svnman software has special support for 'svn:externals' via our freeze and unfreeze processes (both of which happen automatically during a release).
The 'svn:externals' specification format allows for the optional specification of a repository revision number to 'pin' an external project at a specific revision. When pinned an 'svn:externals' definition will always checkout the same version of the external dependency, as indicated by the revision number specified in the pinning. When unpinned the HEAD revision of the external dependency will be used (during checkout and update etc).
As an example you can see an 'svn:externals' definition on one of my projects, jj5-bin:
Look down the bottom of the page for the above URL and you will see the 'svn:externals' property and its configuration, like this:
bugslist https://www.progclub.org/svn/pcrepo/bugslist/branches/0.2 svnman https://www.progclub.org/svn/pcrepo/svnman/branches/1.0
This configuration causes the 'bugslist' and 'svnman' software to be included as an external project for the 'jj5-bin' software. The 'svn:externals' definition from the above is on the version branch and therefore has no revision number specified and thus, being unpinned, tracks HEAD. However a released version of jj5-bin will be pinned, see for example:
Look down the bottom of the page for the above URL and you will see the 'svn:externals' property has been configured to point to a specific revision number of -r7622:
bugslist -r7622 https://www.progclub.org/svn/pcrepo/bugslist/branches/0.2 svnman -r7622 https://www.progclub.org/svn/pcrepo/svnman/branches/1.0
All in all 'svn:externals' is a very important Subversion feature which enables much of the functionality of svnman.
Pinning
So 'pinning' is an optional feature of 'svn:externals'. An 'svn:externals' definition can be "unpinned", in which case the HEAD revision is used, for example:
svnman https://www.progclub.org/svn/pcrepo/svnman/branches/1.0 bugslist https://www.progclub.org/svn/pcrepo/bugslist/branches/0.2
Or it can be "pinned", in which case the indicated revision is used, for example:
svnman -r7622 https://www.progclub.org/svn/pcrepo/svnman/branches/1.0 bugslist -r7622 https://www.progclub.org/svn/pcrepo/bugslist/branches/0.2
So with the above 'pinned' libraries revision 7622 (-r7622) will be used when they are checked out, not the HEAD revision.
Note that the freeze process will recursively pin 'svn:externals' on 'ext' directories, but 'svn:externals' can be pinned by processes other than freeze; particularly with the --pin-externals option used with `svn cp` during tagging operations, or manually, with `svn propedit`.
Feature flags
A feature flag is a software setting that enables (or disables) a particular feature. The idea is that you can do new feature development with the feature disabled in production, and then enable the feature in production when it is ready. This can avoid the need for "feature branches" and allow programmers to coordinate their changes within a shared version branch. See What is a “feature flag”? for more information.
ViewVC
The ViewVC software can be used for browsing a Subversion repository via the web. Our svnman software has basic support for ViewVC integration you can see the browse subcommand for more info.
BASH
The bash shell is our Unix shell of choice. You don't need Bash to run svnman but it is used by our build scripts.
PHP
The svnman software is written mostly in the PHP programming language which we^H^HI love! :)
Other bits and pieces are done with JSON, Subversion, and BASH.
Ubuntu
This software was developed and tested on Ubuntu 18.04 LTS.
JSON
We use the JavaScript Object Notation format for our configuration data.
$PATH
When you install svnman you should make sure a symlink to 'bin/svnman.php' is in your $PATH environment variable.
$HOME
We rely on the $HOME environment variable being set to indicate your home directory. We need to know where your home directory is so that we can save and load your configuration data (see config).
PHPBOM
Our svnman utility has first-class support for our PHPBOM library. Basically when you use svnman to create a new project you can optionally have the PHPBOM library automatically included in your project.
VERSION
Supported version numbers are in the format MAJOR.MINOR.PATCH. See versioning for more info.
NOTE
We often put notes in our code. The format is something like this:
// {date} {user} - NOTE: {note}
Where {date} is in ISO 8601 format (yyyy-mm-dd) and the {user} is the username of the person who left the note. A {note} is just some text that aims to be helpful and usually relates to some code that follows the note itself.
We also use a similar format for TODO items etc. These formats are supported by bugslist which we use to generate documentation.
AKA
The acronym "AKA" stands for "Also Known As".
Generated documentation
The following documentation is automatically generated from the code.
Command-line interface
general usage: svnman SUBCOMMAND [ARG...] [DIR...] A Subversion project management tool. Type `svnman help <subcommand>` for help on a specific subcommand. Type `svnman version` to see the program version. Type `svnman errors` to see information about possible program errors.
- find us on the web: https://www.progclub.org/wiki/svnman
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
SUBCOMMAND
Available subcommands:
- config
- settings
- info
- create
- list (or ls)
- checkout (or co)
- sync
- commit (or ci)
- maint
- freeze
- unfreeze (or thaw)
- release
- bump-minor
- bump-major
- browse
- netbeans
- gen-doc
- gen-vars
- fix-version
- add-keywords
- strict-php
Arguments
Available arguments:
--quiet
-q [--quiet] .........: suppress error/warning/debug output
--debug
--debug ..............: output extra info for debugging
--alias
--alias ALIAS ........: name of a repository alias; see the 'config' subcommand for more information
--location
--location URL .......: location of the repository
--working-base
--working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped.
--working-copy
--working-copy DIR ...: directory containing the working copy; if unspecified the working copy will go under --working-base in a directory calculated using the --project and the MAJOR.MINOR version such as e.g. svnman-1.0
--viewvc
--viewvc URL .........: ViewVC URL for the repository; see the 'browse' subcommand for notes on how this setting is used
--repo
--repo ALIAS|URL .....: Subversion repository to operate on; note that if you nominate an ALIAS then other options (such as --working-base etc) can be inferred from your config file
--project
--project NAME .......: name of the project; this will be used in the repository as the project name and also as part of the working copy path (if --working-copy is unspecified)
--project-code
--project-code CODE ..: project code (lowercase); generated from --project if unspecified
--project-const
--project-const CONST : project const (uppercase); generated from --project-code if unspecified
--no-checkout
--no-checkout ........: don't checkout into working copy
--checkout
--checkout ...........: checkout into working copy [default]
--no-trunk
--no-trunk ...........: trunk is not updated
--trunk
--trunk ..............: trunk is updated
--auto-trunk
--auto-trunk .........: trunk updated if project is on latest version branch [default]
--no-phpbom
--no-phpbom ..........: don't configure the PHPBOM library [default]
--phpbom
--phpbom .............: configure svn:externals on 'lib' DIR for latest PHPBOM release; when using the PHPBOM library some extra files are automatically generated too
--phpbom-dev
--phpbom-dev .........: configure svn:externals on 'ext' DIR for development PHPBOM library; when using the PHPBOM library some extra files are automatically generated too
--no-netbeans
--no-netbeans ........: don't create a NetBeans project [default]
--netbeans
--netbeans ...........: create a NetBeans project in the working copy
--no-mudball
--no-mudball .........: don't configure the MudBall library [default]
--mudball
--mudball ............: configure svn:externals on 'lib' DIR for latest MudBall release; when using the MudBall library some extra files are automatically generated too
--mudball-dev
--mudball-dev ........: configure svn:externals on 'ext' DIR for development MudBall library; when using the MudBall library some extra files are automatically generated too
--topmost
--topmost DIR ........: the 'topmost' directory within the project root. Is typically one of "branches", "tags/latest", "trunk", etc. The default value is "branches"
--version
--version DIR ........: the path to the version (within --topmost). May be a version number in the form X.Y or in the form X/Y/Z etc. If unspecified the latest version will be used
--message
-m [--message] STRING : `svn commit` message; the commit message is always optional; we recommend not using it, but that is a matter for you
--dry-run
--dry-run ............: when specified on supported subcommand will not actually apply changes
Argument formats
ARG
An argument is a name prefixed with two dashes, optionally followed by whitespace and a value, depending on the argument. For example:
--no-trunk
Or:
--repo pcrepo
The special argument '--' indicates that all subsequent command-line values are to be treaded as DIRs not as ARGs.
Note that some arguments also support a shorter version, which is usually a dash followed by a single letter. For example --message can be abbreviated as -m.
DIR
A PATH to a directory in the local file system. Absolute and relative paths are supported for input, but if directory paths are stored (such as with working base directories in repository aliases) the absolute paths are computed and stored at the time of configuration not at time of later use.
Note that if no DIRs are provided the current working directory is processed.
FILE
A PATH to a file in the local file system. Absolute and relative paths are supported.
PATH
A location in the local file system. Absolute or relative paths are supported. A path can be to a standard file, directory, symlink, etc. Generally if a directory is required we explicitly document it as a DIR. If your PATH is to the wrong type of file per your SUBCOMMAND/ARG then you can expect to see an error as a result.
URL
A Uniform Resource Locator, typically with a scheme such as:
- http:
- https:
- file:
- svn:
NAME
Name format:
/^[a-z][a-z0-9\._-]{0,42}[a-z0-9]$/
CODE
Code format:
/^[a-z][a-z0-9-]{0,14}[a-z0-9]$/
CONST
Const format:
/^[A-Z][A-Z0-9_]{0,14}[A-Z0-9]$/
ALIAS
Alias format:
/^[a-z][a-z0-9-]{0,14}[a-z0-9]$/
STRING
String format:
/^[^\x00-\x09\x0b\x0c\x0e-\x1f\x7f]*$/
Subcommands
config
config: usage: svnman config ARG...
Configure an svnman repository alias.
A repository alias associates an alias with a repo location, allowing the repo alias to be used as a shortcut for the repo location in commands which accept a --repo argument. A default working base DIR and a ViewVC URL can also be associated with a repo alias.
Note that the config file is in JSON format in:
$HOME/.config/svnman/config.json
If your alias is not already configured then --location is required. If it is already configured the existing location will be retained if a new location is not nominated. If you want to clear an optional setting you can set it to an empty string.
Example usage:
svnman config \ --alias pcrepo \ --location https://www.progclub.org/svn/pcrepo \ --working-base ~/repo/svn/pcrepo \ --viewvc https://www.progclub.org/pcrepo
Required arguments:
--alias ALIAS ........: name of a repository alias; see the 'config' subcommand for more information
Optional arguments:
--location URL .......: location of the repository --working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped. --viewvc URL .........: ViewVC URL for the repository; see the 'browse' subcommand for notes on how this setting is used
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
settings
settings: usage: svnman settings [ARG...] [DIR...]
Report on an svnman repository alias and its settings.
See the 'config' subcommand for configuring the data reported by 'settings'. If the --alias setting is not specified we try to find the appropriate setting based on the current working directory or DIR if specified.
Example usage:
svnman settings --alias pcrepo
Optional arguments:
--alias ALIAS ........: name of a repository alias; see the 'config' subcommand for more information
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
info
info: usage: svnman info [DIR...]
Report Subversion info and version information for an svnman project in DIR.
Version information includes:
- path of the version file
- whether the version file exists or not
- project MAJOR.MINOR.PATCH version number (if version file exists)
- build type (if version file exists)
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
create
create: usage: svnman create ARG...
Create a new project in a Subversion repository.
New projects are created with:
MAJOR version = 0 MINOR version = 1 PATCH version = 1
The odd PATCH version indicates that the initial version is a DEV version.
So basically a new project is just a couple of standard directories in the repository along with an initial version file. Also, if you've included the PHPBOM library, the svn:externals for that will be configured too.
Depending on your command-line options the initial 'branches/0.1' version will be checked out into a working copy for you.
Example usage:
svnman create --repo pcrepo --project my-killer-app
Required arguments:
--repo ALIAS|URL .....: Subversion repository to operate on; note that if you nominate an ALIAS then other options (such as --working-base etc) can be inferred from your config file --project NAME .......: name of the project; this will be used in the repository as the project name and also as part of the working copy path (if --working-copy is unspecified)
Optional arguments:
--project-code CODE ..: project code (lowercase); generated from --project if unspecified --project-const CONST : project const (uppercase); generated from --project-code if unspecified --working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped. --working-copy DIR ...: directory containing the working copy; if unspecified the working copy will go under --working-base in a directory calculated using the --project and the MAJOR.MINOR version such as e.g. svnman-1.0 --no-checkout ........: don't checkout into working copy --checkout ...........: checkout into working copy [default] --no-phpbom ..........: don't configure the PHPBOM library [default] --phpbom .............: configure svn:externals on 'lib' DIR for latest PHPBOM release; when using the PHPBOM library some extra files are automatically generated too --phpbom-dev .........: configure svn:externals on 'ext' DIR for development PHPBOM library; when using the PHPBOM library some extra files are automatically generated too --no-netbeans ........: don't create a NetBeans project [default] --netbeans ...........: create a NetBeans project in the working copy --no-mudball .........: don't configure the MudBall library [default] --mudball ............: configure svn:externals on 'lib' DIR for latest MudBall release; when using the MudBall library some extra files are automatically generated too --mudball-dev ........: configure svn:externals on 'ext' DIR for development MudBall library; when using the MudBall library some extra files are automatically generated too
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
list
list: usage: svnman list [ARG...]
List projects in a Subversion repository, or if no repository nominated lists available repositories from the config file.
In the output project names are prefixed with '^' if the project is in a nonstandard format.
For a project listing available versions are listed. If an available version is in square brackets this indicates that the version is available on the local machine in the standard location for a working copy.
Example usage:
svnman list --repo pcrepo --topmost tags/latest
Optional arguments:
--repo ALIAS|URL .....: Subversion repository to operate on; note that if you nominate an ALIAS then other options (such as --working-base etc) can be inferred from your config file --topmost DIR ........: the 'topmost' directory within the project root. Is typically one of "branches", "tags/latest", "trunk", etc. The default value is "branches"
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
checkout
checkout: usage: svnman checkout ARG...
Checkout an existing project from a Subversion repository.
Example usage:
svnman checkout --repo pcrepo --project my-killer-app --version 0.2
Required arguments:
--repo ALIAS|URL .....: Subversion repository to operate on; note that if you nominate an ALIAS then other options (such as --working-base etc) can be inferred from your config file --project NAME .......: name of the project; this will be used in the repository as the project name and also as part of the working copy path (if --working-copy is unspecified)
Optional arguments:
--working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped. --working-copy DIR ...: directory containing the working copy; if unspecified the working copy will go under --working-base in a directory calculated using the --project and the MAJOR.MINOR version such as e.g. svnman-1.0 --no-netbeans ........: don't create a NetBeans project [default] --netbeans ...........: create a NetBeans project in the working copy --topmost DIR ........: the 'topmost' directory within the project root. Is typically one of "branches", "tags/latest", "trunk", etc. The default value is "branches" --version DIR ........: the path to the version (within --topmost). May be a version number in the form X.Y or in the form X/Y/Z etc. If unspecified the latest version will be used
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
sync
sync: usage: svnman sync [ARG...] [DIR...]
Synchronize working copy in DIR.
The synchronization process is basically:
- chdir to svn working copy base
- svn up
- svnman commit
- svn status
Optional arguments:
-m [--message] STRING : `svn commit` message; the commit message is always optional; we recommend not using it, but that is a matter for you
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
commit
commit: usage: svnman commit|ci [ARG...] [DIR...]
Run maintenance on DIR then commit.
See `svnman help maint` for information concerning the maintenance process. After maintenance (assuming it is successful) an `svn commit` is performed.
Note that if you are running `svn commit` (AKA: `svn ci`) directly then you should make sure you call `svnman maint` to run maintenance *before* an actual commit. If you don't do this the PATCH version number will not be incremented properly. If you absolutely must run `svn commit` directly then make sure you have incremented the PATCH version by two (to an ODD number) in the version file for your project prior to commit. Run `svnman info` if you need to know which file is being used for version info in your current working directory.
Optional arguments:
-m [--message] STRING : `svn commit` message; the commit message is always optional; we recommend not using it, but that is a matter for you
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
maint
maint: usage: svnman maint [DIR...]
Run maintenance on DIR.
Maintenance includes optional code generation and updating of the PATCH version. You should run this before your commits. You can only run maintenance on DEV builds and this is enforced by this subcommand. If your working copy is for a PROD build (i.e. has an even PATCH version number) then you may need to run `svnman fix-version` to remedy the situation.
For the code generation the file 'bin/dev/gen.sh' is executed, if it exists and is executable.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
freeze
freeze: usage: svnman freeze [DIR...]
Freeze external subprojects in DIR.
Only available for projects that are in 'branches'. When frozen svn:externals under the 'ext' directory are pinned to the revision which was current at the time of freezing.
Note that the 'freeze' process is recursive.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
unfreeze
unfreeze: usage: svnman unfreeze|thaw [DIR...]
Unfreeze external subprojects in DIR.
Only available for projects that are in 'branches'. When unfrozen svn:externals under the 'ext' directory are unpinned from a specific revision.
Note that the 'unfreeze' process is recursive.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
release
release: usage: svnman release [ARG...] [DIR...]
Release a project in DIR.
Prior to release projects are frozen, and after release they are unfrozen. When a release is done the starting version must be a DEV build (with an odd PATCH version number), then during the release the PATCH version number will be incremented to an even version number for the release, and after the release the PATCH version number will be incremented again to a new odd version number for use by the next DEV build.
So the release process is roughly:
- freeze
- bump PATCH to next PROD version
- commit
- create tags
- optionally update trunk
- unfreeze
- bump PATCH to next DEV version
- commit
Optional arguments:
--no-trunk ...........: trunk is not updated --trunk ..............: trunk is updated --auto-trunk .........: trunk updated if project is on latest version branch [default]
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
bump-minor
bump-minor: usage: svnman bump-minor [DIR...]
Create a new version branch from DIR, incrementing the MINOR version number.
Note that during a MINOR version bump the PATCH version is preserved. This means that across MAJOR.MINOR versions PATCH version numbers will duplicate and diverge. This is by design. One consequence of this is that the PATCH number indicates, for every MAJOR.MINOR version, pretty much exactly how many commits have been made in that version's entire history.
Note also that the MINOR version number will be updated in both the URL for the branch and in the project version file (so that's in two places).
Optional arguments:
--working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped. --working-copy DIR ...: directory containing the working copy; if unspecified the working copy will go under --working-base in a directory calculated using the --project and the MAJOR.MINOR version such as e.g. svnman-1.0 --no-checkout ........: don't checkout into working copy --checkout ...........: checkout into working copy [default]
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
bump-major
bump-major: usage: svnman bump-major [DIR...]
Create a new version branch from DIR, incrementing the MAJOR version number (and resetting the MINOR version number to zero).
Note that during a MAJOR version bump the PATCH version is preserved. This means that across MAJOR.MINOR versions PATCH version numbers will duplicate and diverge. This is by design. One consequence of this is that the PATCH number indicates, for every MAJOR.MINOR version, pretty much exactly how many commits have been made in that version's entire history.
Note also that the MAJOR version number will be updated in both the URL for the branch and in the project version file (so that's in two places).
Optional arguments:
--working-base DIR ...: parent directory of the working copy; if unspecified it is loaded from the config file (if possible); if unspecified and not configured then checkout options that depend on this setting will be skipped. --working-copy DIR ...: directory containing the working copy; if unspecified the working copy will go under --working-base in a directory calculated using the --project and the MAJOR.MINOR version such as e.g. svnman-1.0 --no-checkout ........: don't checkout into working copy --checkout ...........: checkout into working copy [default]
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
browse
browse: usage: svnman browse
Open current directory in ViewVC in web browser.
This requires ViewVC to be configured via the 'config' subcommand.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
netbeans
netbeans: usage: svnman netbeans
Creates a NetBeans project in the current directory.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
gen-doc
gen-doc: usage: svnman gen-doc
Generates svnman documentation for use in the project wiki.
You can find said documentation here:
Have a look in the 'bin/dev/gen.sh' script to see how documentation generation is done.
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
gen-vars
gen-vars: usage: svnman gen-vars
Generates shell config containing error constants definitions.
You can `source` the output of this command to configure your environment with error info:
`source <(svnman gen-vars)`
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
fix-version
fix-version: usage: svnman fix-version [DIR...]
If the PATCH version number is left on an even value (perhaps due to a failure during `svnman release`) then this subcommand will bump it to the next odd value, making it a valid development PATCH version number again. If the PATCH version number is already an odd value this subcommand does nothing and fails indicating error.
For more info on our version numbers see:
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
add-keywords
add-keywords: usage: svnman add-keywords FILE...
This subcommand will add an svn:keywords property to the FILE specified for the keywords: Date Revision Author HeadURL Id Header
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
strict-php
strict-php: usage: svnman strict-php [ARG...]
This subcommand will run over **.php files and declare strict types on the first line.
SEE: https://stackoverflow.com/questions/48723637/what-do-strict-types-do-in-php
declare( strict_types = 1 );
Optional arguments:
--dry-run ............: when specified on supported subcommand will not actually apply changes
Global arguments:
-q [--quiet] .........: suppress error/warning/debug output --debug ..............: output extra info for debugging
For help on argument formats see `svnman help`.
Errors
Potential svnman error levels and their meaning:
Error level | Error name | Error text | Hint |
---|---|---|---|
0 | ERR_SUCCESS | program completed successfully. | |
10 | ERR_HELP | help (or version/error info) requested. | |
11 | ERR_PHP_ERROR | PHP error. | please let the maintainer know: John Elliot V <jj5@progclub.org> |
12 | ERR_PHP_EXCEPTION | unhandled exception. | please let the maintainer know: John Elliot V <jj5@progclub.org> |
13 | ERR_PHP_ASSERT | assertion failed. | please let the maintainer know: John Elliot V <jj5@progclub.org> |
14 | ERR_NO_ASSERTIONS | "zend.assertions" are not enabled. | enable "zend.assertions" in php.ini. |
15 | ERR_NOT_IMPLEMENTED | functionality not implemented. | |
16 | ERR_NOT_SUPPORTED | situation not supported. | please let the maintainer know: John Elliot V <jj5@progclub.org> |
17 | ERR_NOT_A_DIRECTORY | not a directory. | |
18 | ERR_NOT_A_DEV_BUILD | not a DEV build. | this is a PROD build. For a DEV build increment the PATCH by 1. Try `svnman fix-version`. |
19 | ERR_INVALID_PATH | invalid path. | |
20 | ERR_INVALID_BRANCH_VERSION | invalid branch version. | make sure VERSION in branches/VERSION is in format MAJOR.MINOR. |
21 | ERR_INVALID_VERSION | version discrepancy. | check the branches/VERSION is same as MAJOR/MINOR from version file. |
22 | ERR_INVALID_VERSION_PART | invalid version part. | |
23 | ERR_INVALID_VERSION_FORMAT | version is in an invalid format. | check you've used '.' or '/' as appropriate to your context. |
24 | ERR_INVALID_VERSION_NUMBER | version contains an invalid version number. | can't be 0.0 or 1.0.0 or 1.1.123.456 etc. |
25 | ERR_INVALID_WORKING_BASE | invalid working base. | |
26 | ERR_INVALID_WORKING_COPY | invalid working copy. | do you need to check-in first? |
27 | ERR_INVALID_EXTERNALS | invalid svn:externals. | |
28 | ERR_INVALID_EXTERNALS_DIR | invalid svn:externals directory. | the directory should come first. |
29 | ERR_INVALID_NAME | invalid name. | |
30 | ERR_INVALID_CODE | invalid code. | |
31 | ERR_INVALID_CONST | invalid const. | |
32 | ERR_INVALID_ALIAS | invalid repository alias. | |
33 | ERR_INVALID_STRING | invalid string. | |
34 | ERR_INVALID_VERSION_PATCH | invalid version PATCH. | |
35 | ERR_INVALID_CONFIG | invalid config. | your config file is corrupt, consider deleting it or revise. |
36 | ERR_MISSING_HOME_ENV_VAR | missing $HOME environment variable. | review your shell configuration such as .bashrc. |
37 | ERR_MISSING_ARG_VALUE | missing argument value. | |
38 | ERR_MISSING_ALIAS | missing --alias. | |
39 | ERR_MISSING_LOCATION | missing --location. | |
40 | ERR_MISSING_HOME_DIR | missing $HOME directory. | |
41 | ERR_MISSING_VERSION_FILE | missing version file. | |
42 | ERR_MISSING_VERSION_PART | missing version part. | |
43 | ERR_MISSING_PROJECT_NAME | missing project name. | |
44 | ERR_NO_SUCH_ALIAS | no such --alias. | |
45 | ERR_NO_BROWSER | could not find a web browser. | |
46 | ERR_NO_VIEWVC_URL | could not compute ViewVC URL. | |
47 | ERR_NO_CONFIG | no config. | run `svnman config` and nominate repository settings. |
48 | ERR_NO_CONFIG_LOCATION | no location config. | run `svnman config` and nominate a --location setting. |
49 | ERR_NO_CONFIG_VIEWVC | no ViewVC config. | run `svnman config` and nominate a --viewvc setting. |
50 | ERR_VERSION_CONFLICT_MAJOR | MAJOR version conflict. | check the branches/VERSION indicates same as MAJOR in version file. |
51 | ERR_VERSION_CONFLICT_MINOR | MINOR version conflict. | check the branches/VERSION indicates same as MINOR in version file. |
52 | ERR_PATCH_VERSION_EVEN | PATCH version is even (PROD). | consider running `svnman fix-version` to resolve. |
53 | ERR_PATCH_VERSION_ODD | PATCH version is odd (DEV). | if PATCH version is odd there's no need to run `svnman fix-version`. |
54 | ERR_EXPECTED_BRANCHES | expected "branches". | |
55 | ERR_MKDIR_FAILED | mkdir failed. | |
56 | ERR_CHDIR_FAILED | chdir failed. | |
57 | ERR_NO_EXTERNALS | no externals. | |
58 | ERR_NOT_WORKING_COPY | not an svn working copy. | |
59 | ERR_CANNOT_MAKE_TEMP_DIR | cannot make temp dir. | |
60 | ERR_CANNOT_MATCH_VERSION_PATCH | cannot match version PATCH. | |
61 | ERR_SVN_MISSING | no executable `svn` command. | make sure Subversion is installed. e.g. `apt install subversion`. |
62 | ERR_SVN_DIR_MISSING | no .svn directory found. | make sure you run this command from an svn working copy. |
63 | ERR_SVN_COMMAND_FAILED | svn command failed. | |
64 | ERR_SVN_CANNOT_ACCESS | cannot access svn repository. | |
65 | ERR_SVN_INVALID_INFO | unsupported `svn info` output. | please let the maintainer know: John Elliot V <jj5@progclub.org> |
66 | ERR_SVN_HAS_CHANGES | found uncommitted changes. | |
67 | ERR_SVN_BRANCH_EXISTS | branch already exists. | |
68 | ERR_FILE_WRITE | error writing file. | |
69 | ERR_FILE_CLOSE | error closing file. | |
70 | ERR_FILE_UNLINK | error unlinking file. | |
71 | ERR_FILE_MISSING | file missing. | |
72 | ERR_CODE_GEN_NOT_EXECUTABLE | code gen script not executable. | you may need to run `chmod +x` on your code gen script. |
73 | ERR_CODE_GEN_FAILED | code generation failed. | |
74 | ERR_CONFIG_WRITE_FAILED | error writing config file. | |
75 | ERR_UNSUPPORTED_FILE_TYPE | unsupported file type. | |
76 | ERR_URL_TRUNK | URL is a trunk branch. | make sure your project is in "branches/MAJOR.MINOR". |
77 | ERR_URL_TAGS | URL is a tags branch. | make sure your project is in "branches/MAJOR.MINOR". |
78 | ERR_URL_NOT_A_VERSION_BRANCH | URL is not a version branch. | make sure your project is in "branches/MAJOR.MINOR". |
79 | ERR_NETBEANS_PROJECT_EXISTS | NetBeans project already exists. | if you want to re-create a project delete exiting 'nbproject' dir. |
Links
Generated with bugslist.
- README: https://www.progclub.org/wiki/svnman
- svnman.php: Svnman Installation Guide
- test.sh: ANSI escape codes
- shell.sh: svnman documentation
- shell.sh: ANSI escape codes
- shell.sh: https://stackoverflow.com/a/25492747
- shell.sh: configuring svnman
- shell.sh: suggestions from Jedd
- version.php: inc/version.php
- Manager.php: Creating temporary files in bash
- Manager.php: Version Control with Subversion (svnbook)
- svnman.php: svnman documentation
TODO
Generated with bugslist.
Bugslist
bugslist v0.2.127 (r7322) compiled 2020-03-04 10:49:53 +1100 (Wed, 04 Mar 2020) by jj5 path: /home/jj5/bin/ext/bugslist/bin/bugslist.php Copyright (C) 2016-2021 John Elliot V License GPLv3+: GNU GPL version 3+ <https://gnu.org/licenses/gpl.html>. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
- find us on the web: https://www.progclub.org/wiki/bugslist
HIGH
- TODO: svnman.php: after version bump copy in config file from previous version.
- TODO: svnman.php: when generating inc/version.php put a comment above VERSION_PATCH with a link to the latest inc/version.php on the relevant version branch.
MEDIUM
- TODO: test.sh: we need much more extensive testing here. Make sure all subcommands get used and in various ways.
- TODO: test.sh: we need a failing test here...
- TODO: test.sh: we need a failing test here...
- TODO: test.sh: probably need this test to go into TestRunner_Manager.
- TODO: test.sh: probably need more happy path tests...
- TODO: Manager.php: MudBall boilerplate.
- TODO: Manager.php: put some error handling around this...
- TODO: svnman.php: this spec should probably be moved into the Settings class and be used for input validation.
- TODO: svnman.php: this program needs better reporting. The current "all or nothing" ouutput is no good and needs to be revised. Basically there should be no output on success and only a brief error message on failure. The current verbose output can be retained for if a --debug or --verbose option is added.
- TODO: svnman.php: need to support other version file formats. Especially *.cfg and maybe *.ini formats. Note that *.cfg file format is a key value format that is compatible with Unix shell environment config.
- TODO: svnman.php: add a --debug command-line option. Be less verbose if it's not specified.
- TODO: svnman.php: add a 'latest-branch' subcommand that reports the current branch and the latest branch (and if they're the same or different).
- TODO: svnman.php: add support for 'browse' subcommand.
- TODO: svnman.php: clean up after ourselves, delete temp files and directories...
- TODO: svnman.php: add support for --tarball generation during release.
- TODO: svnman.php: add a --json argument which causes program output to be in stable JSON format for better software integration options. Enable JSON output for 'version', 'errors', and 'help' too.
- TODO: svnman.php: in gen-vars subcommand support --prefix option for putting env var names in a namespace...
- TODO: svnman.php: add --error ERROR_CODE|ERROR_NAME option to `svnman errors` which will print out detailled error information for the particular error indicated.
- TODO: svnman.php: add a --bug BUG_NUMBER argument. The BUG_NUMBER to be included in commit messages.
- TODO: svnman.php: when updating version file, don't just update a single file, but update all version files, allowing for there to be multiple version file formats used in a single project. This will entail verifying the all version files agree with each other as regards the version number.
- TODO: svnman.php: grep for ERR_ constants and report if <= 1 (i.e. declared but unused).
- TODO: svnman.php: svnman get-error-code --error-name ERROR_NAME
- TODO: svnman.php: svnman get-error-name --error-code ERROR_CODE
- TODO: svnman.php: svnman get-error-info --error ERROR_NAME|ERROR_CODE
- TODO: svnman.php: if --phpbom is nominated during `svnman create` then write the version file to src/code/0-bootstrap/2-version.php and not to inc/version.php.
- TODO: svnman.php: only output stack trace on error if --debug is specified or error hint === PLEASE_INFORM.
- TODO: svnman.php: support single and double quotes on strings in *.cfg files
- TODO: svnman.php: add support for a 'get' subcommand. Will get the latest version (or a specified version) of a project from Subversion and check it out into a local working copy (usually under the working base). If no project name is specified then list available projects.
- TODO: svnman.php: svnman 'status' subcommand.
- output the state of all svn:externals
- report all DEV MAJOR.MINOR versions (branches/MAJOR.MINOR)
- report all PROD MAJOR.MINOR versions (tags/latest/MAJOR.MINOR)
- it would be nice to figure out if a project is a candidate for release
- i.e. if it hasn't very recently been released
- check PATCH number probably, or maybe Revision.
- i.e. if it hasn't very recently been released
- TODO: svnman.php: ensure all external projects have no changes before operating
- TODO: svnman.php: for `svnman list` support formatting options:
- --format console-list
- --format console-table
- --format wiki-list
- --format wiki-table
LOW
- THINK: Manager.php: do we want to just automatically mkdir -p the working base..?
- THINK: svnman.php: do we want an optional argument --version-file for manually nominating the version file..? (At the moment we prefer convention over configuration.)
- THINK: svnman.php: enable JSON output for tests?
- THINK: svnman.php: consider adding an interactive mode that will confirm options or ask questions.
- THINK: svnman.php: if we're gonna allow refactoring of error name constants we might want a compatibility thing that aliases old/deprecated names to new names. But such a facility isn't necessary yet.
- THINK: svnman.php: think about what other files/directories we might want to create upon `svnman create` if --phpbom is specified.
- THINK: svnman.php: hint for unauthorised --non-interactive `svn` operations which fail: "please authenticate"
- THINK: svnman.php: operate without version file for legacy support? (to test delete the version file and run subcommands)
- THINK: svnman.php: should we create a 'man page' for svnman..? That might be fun. I've never created a man page before!