[REP Index] [REP Source]
REP: | 110 |
---|---|
Title: | SCM-like rosinstall command structure |
Author: | Thibault Kruse <kruset at in.tum.de> |
Status: | Draft |
Type: | Informational |
Content-Type: | text/x-rst |
Created: | 11-Jun-2011 |
Post-History: | 11-Jun-2011, 10-Aug-2011, 03-Mar-2012 |
Contents
This REP presents an alternative to the rosinstall [1] command-line interface to a command-based syntax. The command-based syntax is inspired by SCM tools like svn, git, and hg as well as several other ros commands like rosnode or rosservice, and is intended to improve the usability of rosinstall as well as expose more functionality. Common use cases of rosinstall are described and compared with the proposed changes.
The name "rosinstall" does not fit into an SCM like tool as it contains a verb "install" in its name, which is confusing. The name rosws for rosworkspace is a suggestion based also on other activities around rosinstall. (see https://code.ros.org/lurker/message/20110711.160222.666ecfe4.en.html)
The command by default uses the context to determine which folder to use as target of the operations. Two location types are relevant, the workspace folder, and folders of entries.
The workspace folder must contain a .rosinstall file to be recognized as such. The rosws command will consider the first such folder in the chain of the current directory and its parents. The rosinstall command may also rely on the ROS_WORKSPACE environment variable to specify a workspace. If both approaches detect a suitable folder, the command will fail with an error message indicating the ambiguity. The user may specify a target workspace folder with the same option for all commands. This is the preferred approach for scripting with rosws.
To determine what entry a user wants to work on for certain commands, the concept of a localname is used in what follows. The localname is historically an absolute filepath or a relative path relative to the workspace folder. Commands which accept a localname argument will first attempt to resolve that argument against the list of known localnames. If that fails, the commands will fall back to choosing a workspace entry which has the same path in the filesystem, even if the localname does not match. As an example, rosws diff . In a tree with localname foo is equivalent to rosws diff foo. Finally, some commands may fall back to interpret such an argument, if it is the only one, and in the absence of a specifying option, as a workspace folder if the command also accepts a workspace folder.
The command creates an initial environment for the other commands to work. This is analogous to scm syntax. Its main purpose is to explain the tool to the user, who understands that the location used here is going to be a special location further on.
The command also generates three initial files, setup.sh, setup.bash and setup.zsh, which when sourced set up environment variables according to the .rosinstall file in the same folder. Those files wll only be overwritten by the rosws regenerate command.
--catkin, --cmake-prefix-path
Options retain semantics as in rosinstall
This command processes several entries from a given URI source
The command merges new entries (command line or changed in .rosinstall) with existing entries (if a .rosinstall is present). The strategy is to replace existing entries rather than adding whenever possible. This is the case when an existing and a new entry have the same target path, the same SCM type, and a similar SCM configuration (e.g. same URI root).
The strategy fails whenever there are two entries with the same target path but replacing is impossible with the strategy above.
When successfull, the command will append the new entries to the end of the .rosinstall file.
URI can be a path to a rosinstall file, to a local directory containing a .rosinstall.
The command will fail when there are entries with duplicate target paths.
The command calculates the change to the configuration. If the change merely consists of adding entries, this is executed. Else, the user is presented with an overview of planned changes, roughly similar to what the linux aptitude tool may present. The user can then interrupt the operation. An option exists to not ask for confirmation.
Options:
The merge options apply whenever two elements have equivalent localnames (pointing to the same directory)
--merge-keep | Existing entries will remain unchanged |
--merge-replace | |
Existing entries will be overwritten in place | |
--merge-kill-append | |
Exiting entries will be removed, new ones appended to the end | |
--confirm-all | Do not ask for confirmation |
The command serves to add or modify a single entry of the config and is in particular aimed at users entering the entry information themselves rather than relying on some other source of information.
For adding an entry, the common case is to add an SCM entry. The syntax would then be
rosws set localname uri --scmtype --version=version
Options:
--svn | Subversion SCM |
--hg | Mercurial SCM |
--git | git SCM |
--bzr | bazaar SCM |
--tar | tar as source (unofficial experimental feature) |
--detached | no SCM |
--version-new | the version specification to use |
- single dash means read from stdin (similar to tar command)
Option -version would go against the GNU standard of a global --version option giving the version of a command line tool.
Examples:
$ rosws set robot_model --hg https://kforge.ros.org/robotmodel/robot_model $ rosws set robot_model --version robot_model-1.7.1 $ rosws set robot_model --detached
The command checks out or updates the given subtrees or all subtrees from their respective SCM provider and URL.
--continue-on-error | |
Continue despite checkout errors | |
--delete-changed-uris | |
Delete the local copy of a directory before changing uri. | |
--abort-changed-uris | |
Abort if changed uri detected | |
--backup-changed-uris=BACKUP_CHANGED | |
backup the local copy of a directory before changing uri to this directory. |
Options retain their semantics from current rosinstall.
Examples:
$ rosws update -t ~/fuerte $ rosws update robot_model geometry
This serves to explain the current environment to the novice user, and provide an overview of it. It is supposed to give an overview of the environment and its state. The reference implementation lists the interpreted ROS_ROOT and the ordered paths in the ROS_PACKAGE_PATH. It also provides status information about the local directories, such as whether they exist and whether their current version matches the .rosinstall.
Options:
--data-only | just the data, no headers or text |
--no-pkg-path | does not print ROS_PACKAGE_PATH |
--pkg-path-only | |
Shows only ROS_PACKAGE_PATH separated by :. Supercedes all other options. | |
--only | Shows only given comma-separated attribute(s) separated by , |
--yaml | prints rosinstall format yaml for backing up the current config |
These options are mainly intended to allow scripting based on rosinstall.
Examples:
$ rosws info -t ~/ros/fuerte $ rosws info robot_model $ rosws info --yaml $ rosws info --only=path,cur_uri,cur_revision robot_model geometry
removes entries with given localnames from the .rosinstall file
This command batch-calls SCM status. The output is the concatenation status commands for all versioned entries.
Options:
--untracked | also shows untracked files |
This command batch-calls SCM diffs. The output is the concatenation of diff commands for all versioned entries.
Such a feature was suggested on ros-developers. The reference implementation shows how this could be done. However the solution is neither very robust nor flexible for SCM diff options.
There is room for ambiguity when the version specified in the .rosinstall does not match the version in the directory. A warning should be given on stderr at least.
This command regenerates the setup.sh, setup.bash and setup.zsh files that setup a shell environment. The rosinstall command overwrites these files on each invocation for historical reasons.
There is as of today no need to regenerate these files even if the .rosinstall file changed in acceptable use-cases. The only cases where the files would be changed is when configuring a workspace against a changed ROS distribution, or after an update of the rosws tool.
Options
--catkin --cmake-prefix-path
Options retain semantics as in rosinstall
The following are a list of use cases for rosinstall. U1-U6 are based on use cases described in the rosinstall documentation [1].
The new command syntax examples usually have several alternatives to use context or options to specify the workspace to operate on..
E.g. Developing on top of boxturtle shared install
rosinstall ~/workspace /opt/ros/boxturtle http://www.ros.org/rosinstalls/wg_boxturtle_devel.rosinstall
New command example:
rosws ~/workspace /opt/ros/boxturtle cd ~/workspace rosws merge http://www.ros.org/rosinstalls/wg_boxturtle_devel.rosinstall rosws update
E.g. Full source checkout
rosinstall ~/workspace http://www.ros.org/rosinstalls/boxturtle_pr2all.rosinstall
New command example:
rosws ~/workspace http://www.ros.org/rosinstalls/boxturtle_pr2all.rosinstall
E.g. Developing a stack against a full tree
rosinstall ~/workspace http://www.ros.org/rosinstalls/boxturtle_pr2all.rosinstall my_stack.rosinstall
New command example:
rosws ~/workspace http://www.ros.org/rosinstalls/boxturtle_pr2all.rosinstall cd ~/workspace rosws merge my_stack.rosinstall rosws update
E.g. Adding a rosinstall layout to an existing workspace
rosinstall ~/workspace http://www.ros.org/rosinstalls/wg_boxturtle_devel.rosinstall
New command example:
cd ~/workspace rosws merge http://www.ros.org/rosinstalls/wg_boxturtle_devel.rosinstall rosws update
rosinstall ~/workspace
New command example:
cd ~/workspace rosws update sometree
You can manually edit the file .rosinstall in a rosinstall managed workspace and then call rosinstall ~/workspace.
New command example:
cd ~/workspace rosws set stackname --version=newversion
e.g. taking the sources from trunk, using roslocate
roslocate info common_msgs | rosinstall add .
New command example:
cd ~/workspace roslocate info common_msgs | rosws merge -
You can manually edit the file .rosinstall in a rosinstall managed workspace and then call rosinstall ~/workspace
You can manually edit the file .rosinstall in a rosinstall managed workspace and then call rosinstall ~/workspace
New command example:
cd ~/workspace rosws remove foo
using diverse file exploration tools
rosinstall ~/workspace --generate-versioned-rosinstall=GENERATE_VERSIONED
New command example:
cd ~/workspace rosws info --yaml > GENERATE_VERSIONED
Users should generall avoid doing this, as it can lead to failure in many ways.
Therefore not implementing the usecase in this REP, meaning user has to manually modify .rosinstall and call rosinstall
rosinstall ~/workspace /path/to/other/workspace
New command example:
rosws init ~/workspace /path/to/other/workspace
The user has some ROS stack in directory foo, and want to move that stack to directory bar. This means moving the files as well as updating the .rosinstall and the setup.sh.
Will not be supported for now.
An expert user can change path, version, scm, entry order, etc. in his rosinstall. In some cases he then just wants his setup.sh file to be regenerated, in other cases he may want to update directories to specific revisions.
rosinstall ~/workspace
New command example:
cd ~/workspace rosws update foostack rosws regenerate
When the user works on several interdependent stacks, he wants to create a unified diff of those stacks against their checked-out revision.
rosinstall ~/workspace --diff
New command example:
cd ~/workspace rosws diff
When the user works on several interdependent stacks, he wants to see what files are currently in a changed status in their respective SCM.
rosinstall ~/workspace --status
New command example:
cd ~/workspace rosws status
All rosinstall use-cases deal with a user trying to maintain a ROS environment on a local machine. A ROS environment means the assignment of values to ROS_PACKAGE_PATH, PATH, PYTHONPATH and ROS_MASTER_URI, as well as further changes to support ROS toolchains.
Given the description, a user of rosinstall needs to be aware of the following artifacts:
As a user is free to manipulate entry in the configuration files, a major cause for errors are mistakes during such modifications. As an automated tool, rosinstall currently only knows of this: The user may have changed the rosinstall file, the user may have provided additional locations, now a new .rosinstall file may have to be merged with additional locations, and new setup.* files have to be generated.
An early attempt for this REP tried to provide different commands for different use-cases, such as init, remove, add and update. However the code for all those commands had in all cases to remain largely similar to cope with the situation where a user had manually changed his or her .rosinstall, or filesystem.
The list of use-cases thus only displays the range of distinctive usages of rosinstall, but does not provide help into splitting up the main functionality into many small commands.
The rosinstall tool, while useful, has a command-line syntax that can be difficult for beginners of ROS to become familiar with. Users who are intimidated by rosinstall can resort to manually creating source trees and maintaining ROS_PACKAGE_PATH by hand. Improving the usability of the rosinstall tool can improve the ROS experience for beginner users as well as introduce advanced users to more powerful features.
The extended command structure allows to perform a broader range of operations concerning multiple SCMs, and mere investigative commands.
Breaking down functionality helps self-explaining of the tool.
Also this makes it easier to extend rosinstall with other functions, and to use rosintall in scripts (e.g. provide a curses/tk-based rosinstall ui).
Another problem are the --options. Those are only required in specific use-cases, but in the current solution the user may provide them in any case, and thus the user will have difficulties to tell what his choices for options are, given his intention. Having distinct commands allows a help function to quickly tell the user what options are available for his specific intention.
The SCM like structure also allows code completion to provide command choices, which is a significant help for users when learning a new tool.
The vision of the source code is that it will one day in large parts be moved out of rosinstall to provide ROS-independent functionality for managing directories of mutliple SCMs. However the rosinstall functionality of generating setup files for ROS environments will remain important. Therefore a name change to rosws is suggested rather than a ROS-independent name.
The current rosinstall command structure allows a command such as:
rosinstall ~/workspace /opt/ros/diamondback ~/workspace2 ~/workspace/foo ~/download/temp.rosinstall
The intention of the user typing this cannot be inferred from the command, nor can what the tool will do be inferred from the syntax. The key idea is to have a syntax that allows the user to express a specific intention and to understand what the tool will do.
The commands info, diff, and status are self-explanatory.
The word install was dropped completely with the broad functionality it offers in rosinstall. install makes users shy away from usage fearing they might corrupt their debian installation with a tool.
The set and merge commands are somewhat ambiguous, as the user would need to use them for multiple purposes of adding entries or modifying versions of entries. However the different use-cases are algorithmically so similar that own commands for each seem superflous.
Rejected names include:
add, edit, modify, read, load, import, change
The rosinstall setup files remain unchanged.
Current rosinstall syntax is:
Usage: rosinstall PATH [<options> ...] [URI]... Options: --version show program's version number and exit -h, --help show this help message and exit -n, --nobuild skip the build step for the ROS stack --rosdep-yes Pass through --rosdep-yes to rosmake --continue-on-error Continue despite checkout errors --delete-changed-uris Delete the local copy of a directory before changing uri. --abort-changed-uris Abort if changed uri detected --backup-changed-uris=BACKUP_CHANGED backup the local copy of a directory before changing uri to this directory. --generate-versioned-rosinstall=GENERATE_VERSIONED generate a versioned rosintall file
--generate-versioned-rosinstall is a special case and is replaced by rosinstall snapshot.
This will be fulfilled by rosws install.
The change in command syntax impacts rosinstall based tools such as the new proposal for a rosworkspace.
As originally developed by Tully Foote.
Commands are:
rosinstall PATH [options] [URIs]
with a 4 Phase model, Merging, Checking out, Generating setup, bootstrapping ROS serving most use-cases and --generate-versioned-rosinstall being an exceptional command
Similar to the commands provided in the REP, some of the functionality could be provided by additional --options.
e.g.:
rosinstall --info rosinstall --check rosinstall --diff rosinstall --status
This is less useful for bash completion and focused help.
As initially suggested for this REP, all commands require the path on which to work as the first argument.
Commands are:
rosinstall <command> PATH [options] rosinstall <command> PATH [options] [URIs]
The SCM-like Designs are in line with the other ROS tools. However, SCM tools usually drop the PATH argument and work in the current directory tree.
Inferring the path from context can be done to varying degrees, like ignoring the ROS_WORKSPACE variable or only considering the current folder, not its ancestors as candidates.
Another alternative is to try first interpreting any first argument as a workspace folder, however this may conflict with the syntax of command set.
The install command suggested provides support for several use cases which could be further split up into different commands, e.g. add and apply. See Rejects.
Reference implementation is provided with the latest rosinstall release.
Ideas for rosinstall commands that were dropped for this REP, but may become interesting later:
In 2012 there was a second surge to realize the REP. In this it was decided to make a more significant step away from the rosinstall design. As a consequence, certain ideas were brought up and rejected:
A command doing many things at once confuses and scares the occasional user Similarly commands set, merge nad update only do one thing, and do not allow doing more than one thing.
It could be convenient if the tool did or offered to checkout/update tree entries after a set/merge operation. This can be added as an option in the future if users want it.
These commands could technically take many uri arguments instead of maximally one. The decision to allow only one is to help users understand the syntax. The problem with many arguments we saw with rosinstall is that users could not read from the syntax whether the second argument had a special semantic or not, or whether the order of the arguments mattered.
rosinstall was provided in support of early ROS releases, this REP is provided in the wake of ROS fuerte, which makes significant changes to how a ROS environment is set up. rosws can have a fresh start with fuerte only providing minimal support for ealier distros. In particular rosws will not insist on having a ROS stack, and will not build ros or ros_comm even after source checkouts, nor have an option to do so. A future development could be to even drop generation of the setup.* files.
With SCM providers, it is possible to checkout a new local copy from a url without giving a target folder name. The same could be achieved with the rosws set syntax. However this makes the syntax more confusing, and in many cases we want the user to be aware of names because the repository names often have dashes where the localname should have underscores.
The command is just a variant of rosws info and can be a --option
Both commands add/modify entries, so the case was made to unify them. It was rejected after lengthy discussions for these reasons: There is the fact that the 1st argument is mandatory for set, but not useful as localname for merge. There are the different -- options for the different cases. For the user, it should be clear whether his focus is some "remote" resource containing a set of many yaml entries, or on a single entry to add/change. That split is also the split of commands. The user won't be surprised by tab completion options --hg (or just hg as positional argument) or --version when merging with rosinstall files. They would make no sense, but code completion cannot know that. The localnames wont get in the way of tab completion user when wanting to point to a local xyz.rosinstall file. It is true that merge is semantically like n calls to set, except it is an atomic operation (all succeed, or all fail). In the far future, we might think of nested workspaces having state and version of their own and defining commit() and add()and update() actions. Then we could have a different type for the "set" command, BUT this would be very different semantics from the merge command, and the merge command would not become obsolete. This possibility should also indicate why merging the set and merge command above would hinder things in the future.
The set semantics could be cleaner if it followed the principle that always a full entry (scmtype, uri, version) must be provided. This is however unnecessarily tedious when the user just wants to change one of the details of an existing entry
The split has the advantage that more warnings can be provided in case the user tries to add an entry which overlaps another. However a confirmation step is sufficient. Also this would allow having mandatory positional parameters for scmtype and uri in the add case, and optional ones for the edit case, but two different syntax structures for very similar cases would be confusing as well.
positional arguments like hg, git and svn do not work well with an optional third positional argument URI.
set has option --detached to remove all scm information. The case was made to make this a command of its own, in particular for a fuse set/merge command. But it fits better with the set - merge split.
removal is an instance of modifying, so it could be unified with set as a --option. However the end effect of a set operation is always that something exists afterwards, so these semantics get muddied by remove as an option.
When using merge or set, a decision is when an overlapping entry exist, whether to replace it in place, or whether to remove the existing and append the new one at the end. rosinstall has the latter semantic because it conveniently implies that it is possible to ensure an ordering of entries in the config file by ordering them in the argument list.
For novice users however this behavior is confusing and also hard to describe. The default semantics for merge is therefore to replace the entry in place. An option exists for merge to change that behavior.
The following attempts were rejected in the first REP draft in 2011
In the second draft, those command were resurrected in particular in the absence of an all encompassing rosws install command.
Those commands were too similar to rosws install and their behavior to bulk update and regenerate all trees conflicted with the semantics sugested by their name.
Those commands make the initial version of the REP more complex to discuss and harder to implement, therefore they were left out.
[1] | (1, 2) rosinstall (http://www.ros.org/wiki/rosinstall) |
Copyright (c) 2011 by Thibault Kruse. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v0.1 or later (the latest version is presently available at http://www.opencontent.org/openpub/).