INTERFACE--------------------------------------------------------------------------- This is an interface for package version control using CVS. Currently there are no other implementations available. If they get added, probably the interface will not only have to be abstracted in a technical, but also in a semantical way. I try to minimize the assumptions made by this interface, but you never know in advance...PkgVC ; IMPORT TextSeq, TextTextTbl, TextTupleSeq, Pathname; IMPORT APN AS APN, APNSeq AS APNSeq, Tag, TagSeq; IMPORT Confirmation, MsgIF, TextLockInfoTbl; CONST Brand = "PkgVC 2.0";
The VC-interface is realized by a singular object (w.r.t. network objects), that is accessable via the global variable VC of type PkgVC.T. (Do not create other instances, since they can only be initialized within the implementation module.) All version control funktions are realized as methods of this object.
Please note that sometimes tags are passed as TEXTs, sometimes as Tag.Ts. I am not yet sure if this is a bug or a feature... The output of the last action of the underlying version control system (CVS) can be accessed via the object variable lastVCMsg. Every error situation reported by the underlying CVS module will raise an PkgVC.E(TEXT) exception, where TEXT represents an appropriate error message.
------------------------------------------------------------------------
TYPE ConfirmClosure = Confirmation.Closure;---------------------------------------------------------------------------
TYPE CommitType = {Major, Minor, Patch};---------------------------------------------------------------------------
TYPE Mode = {Operational, Test};---------------------------------------------------------------------------
TYPE LockType = {None, Binary, All};---------------------------------------------------------------------------
EXCEPTION E(TEXT);---------------------------------------------------------------------------
TYPE T <: Public; Public = OBJECT (*-------------------------------------------------------------*) lastVCMsg : TEXT; (* The last message to stdout resp. an internal result message of the underlying version control system (CVS). *) METHODS (*-----------------------------------------------------------------------*) init(msgif : MsgIF.T := NIL) : T; (* Define default values for everything. *) (*-----------------------------------------------------------------------*) flushCache(); (* Purge any cached version information. *) (*-----------------------------------------------------------------------*) ignorePatterns() : TEXT; (* Return the current patterns for ignored files. *) (*-----------------------------------------------------------------------*) packageRelativePathname(pn : Pathname.T) : Pathname.T RAISES {E}; (* Return a pathname that is relative to the package root directory, if possible. *) (*-----------------------------------------------------------------------*) symbolicRevisionName(tag : Tag.T; avoidHead := FALSE) : TEXT RAISES {E}; (* Return the textual representation of a tag, considering the special meaning of Tag.Head and Tag.Tip in the environment of the current package. *) (*-----------------------------------------------------------------------*) setPackageRoot(rootDir : APN.T) RAISES {E}; (* Set the global root directory of the package we are working on. Get the name of the package from this directory. *) (*-----------------------------------------------------------------------*) setMode(m : Mode); (* Set mode to operational (default) or test (no actions are executd. *) (*-----------------------------------------------------------------------*) setEnvironment(env : TextTextTbl.T; repoMapping : TextTupleSeq.T := NIL); (* This is the general interface to pass various (possibly) implementation dependent parameters to the underlying version control system. The current (CVS-only) implementation uses the following values, if they exist: | o editor | o repository | o cvspath | o dcvs-repository | o dcvspath | o prefer-dcvs | o vc-options | o vc-locking (none|lazy, binary|default, all|strict) *) (*-----------------------------------------------------------------------*) getEnvironment() : TextTextTbl.T; (*-----------------------------------------------------------------------*) lockingScheme() : LockType; (*-----------------------------------------------------------------------*) newCollection(path : APN.T; msg : TEXT := NIL; msgFile : APN.T := NIL) RAISES {E} ; (* Create a new empty collection at `path' and put it under version control. *) (*-----------------------------------------------------------------------*) checkout(pkgname : TEXT; tag : Tag.T) RAISES {E} ; (* Checkout the package using symbolic revision `tag' from the repository. Return any results displayed by the underlying version control system in `res'. `Tag' may have the special value `Tag.Head'. *) (*----------------------------------------------------------------------*) update(tag : Tag.T) RAISES {E} ; (* Update the package using symbolic revision `tag' from the repository. Return any results displayed by the underlying version control system in `res'. `Tag' may have the special values `Tag.Head' and `Tag.Tip'. *) (*----------------------------------------------------------------------*) merge(tag : Tag.T; tag2 : Tag.T := NIL; with_d_option : BOOLEAN := FALSE) RAISES {E} ; (* Merge in changes using symbolic revision `tag' from the repository. If `tag2' is not NIL, merge only the differences between `tag' and `tag2'. *) (*----------------------------------------------------------------------*) log(fn : APN.T := NIL) : TEXT RAISES {E} ; (* Return the package log if fn = NIL, else the corresponding file log. *) (*----------------------------------------------------------------------*) niceLog(fn : APN.T := NIL; displayTags := TRUE; displayRevs := TRUE; displayLog := TRUE) : TEXT RAISES {E} ; (* Return a nicely formatted package or file log. *) (*----------------------------------------------------------------------*) diff(from : Tag.T := NIL; to : Tag.T := NIL; udiff := FALSE; cdiff := FALSE; flist : APNSeq.T := NIL) : TEXT RAISES {E} ; (* Return a diff between the current version and the repository or between the versions identified by `from' and `to'. If `flist' is not NIL, consider only the files in the list to produce the diff. *) (*----------------------------------------------------------------------*) annotate(flist : APNSeq.T := NIL) : TEXT RAISES {E}; (* Return an annotated file listing *) (*----------------------------------------------------------------------*) commitChanges(ct : CommitType; msg : TEXT := NIL; msgFile : APN.T := NIL) RAISES {E} ; (* Commit any changes made to the local workspace of the package to the current branch (usually the main trunk). Stick a development tag on the whole package after the commit. Use `msg' or `msgFile' as source for the commit log if they are not NIL. The development tag is of the form `devel_pkgname_major_minor_release'. If `ct' is CommitType.Major, then the next major version is computed and used; if it is CommitType.Minor, the next minor version is computed and used; if it is CommitType.Patch, the next patchlevel is computed and used. *) (*----------------------------------------------------------------------*) commitRelease(ct : CommitType; msg : TEXT := NIL; msgFile : APN.T := NIL) RAISES {E} ; (* Commit any changes made to the local workspace of the package to the current branch (usually the main trunk). Stick a release tag on the whole package after the commit. Use `msg' or `msgFile' as source for the commit log if they are not NIL. The release tag is of the form `release_pkgname_major_minor_release'. If `ct' is CommitType.Major, then the next major version is computed and used; if it is CommitType.Minor, the next minor version is computed and used; if it is CommitType.Patch, the next patchlevel is computed and used. Finally a release stable branch is established for the new release. The branch tag used is of the form `release_pkgname_major_minor_stable'. *) (*----------------------------------------------------------------------*) commitToChangeBranch(changeName : TEXT; changeType : Tag.Kind; ct : CommitType; newBranch := FALSE; msg : TEXT := NIL; msgFile : APN.T := NIL) RAISES {E}; (* Commit changes to a local change branch (for use with DCVS). *) (*----------------------------------------------------------------------*) tagAll(tag : Tag.T; branch := FALSE; force := FALSE) RAISES {E} ; (* Tag all elements of the package with `tag', if it is not yet used. *) (*----------------------------------------------------------------------*) add(obj : APN.T; recursive := FALSE; interactive := FALSE; binary := FALSE) : BOOLEAN RAISES {E} ; (* Add the object denoted by `obj' to the package (i.e. put it under version control). The parameters `recursive' and `interactive' mean their obvious meaning... *) (*----------------------------------------------------------------------*) remove(obj : APN.T; recursive := FALSE; interactive := FALSE) : BOOLEAN RAISES {E}; (* Remove the object denoted by `obj' from the package (i.e. discontinue version control). The parameters `recursive' and `interactive' mean their obvious meaning... *) (*----------------------------------------------------------------------*) setLocking(obj : APN.T; cmd := "on"; recursive := TRUE) RAISES {E}; (* Set strict locking regardless of the currently active locking scheme. *) (*----------------------------------------------------------------------*) lockForEdit(obj : APN.T; recursive := TRUE) RAISES {E}; (* Lock the object denoted by `obj' for editing and make it writable. If the given object is already being edited by others, this provokes an exception. *) (*----------------------------------------------------------------------*) revert(obj : APN.T; recursive := TRUE) RAISES {E}; (* Revert all local modifications made to a file that has previously been locked by `lockForEdit'. *) (*----------------------------------------------------------------------*) editorInfo(obj : APN.T; recursive := TRUE) : TextLockInfoTbl.T RAISES {E}; (* Return a table of CVS locking information for the specified file or directory. *) (*----------------------------------------------------------------------*) editors(obj : APN.T; recursive := TRUE) : TextSeq.T RAISES {E}; (* Return a list of all editors of the given object. *) (*----------------------------------------------------------------------*) lockedByMe(obj : APN.T; recursive := TRUE) : BOOLEAN RAISES {E}; (* <=> The given object is locked for editing solely by the current user. *) (*----------------------------------------------------------------------*) lockedByOther(obj : APN.T; recursive := TRUE) : BOOLEAN RAISES {E}; (* <=> The given object is locked for editing by somebody else. *) (*----------------------------------------------------------------------*) known(obj : APN.T) : BOOLEAN RAISES {E}; (* The object denoted by `obj' is under version control. *) (*----------------------------------------------------------------------*) upToDate() : BOOLEAN RAISES {E}; (* <=> The package is up-to-date *) (*----------------------------------------------------------------------*) modified() : BOOLEAN RAISES {E}; (* <=> Elements of the package have been locally modified (or added or) removed. *) (*----------------------------------------------------------------------*) conflicts() : BOOLEAN RAISES {E}; (* <=> Elements of the package conflict with the repository. *) (*----------------------------------------------------------------------*) tagList(prefix : TEXT) : TextSeq.T RAISES {E}; (* Return all tags beginning with `prefix' *) (*----------------------------------------------------------------------*) tags(prefix : TEXT; fn : APN.T := NIL) : TagSeq.T RAISES {E}; (* Return all tags beginning with `prefix' *) (*----------------------------------------------------------------------*) tagExists(t : Tag.T) : BOOLEAN RAISES {E}; (*----------------------------------------------------------------------*) isSticky(VAR tag : Tag.T) : BOOLEAN RAISES {E}; (* <=> The package is checked out with a sticky tag. Return the appropriate tag if true. *) (*----------------------------------------------------------------------*) isRelease(VAR tag : Tag.T) : BOOLEAN RAISES {E}; (* <=> The package is checked out with a release tag. Return the appropriate tag if true. *) (*----------------------------------------------------------------------*) isReleaseBranch(VAR tag : Tag.T) : BOOLEAN RAISES {E}; (* <=> The package is checked out on a release branch. Return the appropriate tag if true. *) (*----------------------------------------------------------------------*) latestReleaseBranch(VAR tag : Tag.T) : BOOLEAN RAISES {E}; (* <=> There has been a release of this package. Return the appropriate tag. *) (*----------------------------------------------------------------------*) isChangeBranch(VAR tag : Tag.T) : BOOLEAN RAISES {E}; (*----------------------------------------------------------------------*) latestChangeBranch(kind : Tag.Kind; VAR tag : Tag.T) : BOOLEAN RAISES {E}; (*----------------------------------------------------------------------*) currentDevelopmentTag() : Tag.T RAISES {E}; (* Return the current development tag for the package. *) (*----------------------------------------------------------------------*) nextDevelopmentTag(ct : CommitType) : Tag.T RAISES {E}; (* Return the next development tag for the package. *) (*----------------------------------------------------------------------*) currentReleaseTag() : Tag.T RAISES {E}; (* Return the current release tag for the package. *) (*----------------------------------------------------------------------*) nextReleaseTag(ct : CommitType; branch : Tag.T := NIL) : Tag.T RAISES {E}; (* Return the next release tag for the package. *) (*----------------------------------------------------------------------*) currentLocalTag() : Tag.T RAISES {E}; (* Return the current local tag of the package, which is either a sticky tag (if all elements are tagged as sticky), or the current development tag (if no elements are sticky and the package is up-to-date, or the tag that was current when the package was checked out (last entry of PkgTags). *) (*----------------------------------------------------------------------*) (* Support for Package Directories and Package Element Control *) (*----------------------------------------------------------------------*) (* In the package root directory, a listing of all package elements with complete relative pathnames in POSIX notation may reside. This file is named `PkgDirectory' and is usually maintained automatically by the PkgVC module. If it exists when the package root is defined, its contents are read in and cached. *) (*----------------------------------------------------------------------*) packageDirectory() : APNSeq.T RAISES {E}; (* Get the list of files from a Manifest or Directory file if it exists in the package root. Return NIL if no file exists. Raise an exception in case of read errors only. *) (*----------------------------------------------------------------------*) overwritePackageDirectory(dir : APNSeq.T) RAISES {E}; (* Write the list `dir' as the package directory file. *) (*----------------------------------------------------------------------*) updatePackageDirectory(VAR added, removed : APNSeq.T; confirmRemoval := TRUE; confirmAddition := FALSE) RAISES {E}; (* Read the package directory file again and add and remove elements according to its contents. Ask for confirmation according to the third and fourth parameter. *) (*----------------------------------------------------------------------*) addFiles(flist : APNSeq.T) RAISES {E}; (* Put all files in `flist' under version control and update the package directory. *) (*----------------------------------------------------------------------*) (* Operations ignoring the PkgDirectory file *) (*----------------------------------------------------------------------*) versionControlledFiles(includePkgName := FALSE) : APNSeq.T RAISES {E}; (* Return a list of all files that are under version control in the current package. Gather this information directly from the underlying version control machine. *) (*----------------------------------------------------------------------*) checkVersionControlStatus(fl : APNSeq.T; VAR vcFiles : APNSeq.T; VAR unknownFiles : APNSeq.T) RAISES {E}; (* Check all files in `fl' and put those under version control into `vcFiles' and the others into `unknownFiles'. Do not use the PkgDirectory file, but gather the information directly from the underlying version control machine. *) (*----------------------------------------------------------------------*) getFileStatus(VAR added : APNSeq.T; VAR removed : APNSeq.T; VAR modified : APNSeq.T; VAR conflicts : APNSeq.T; VAR needingUpdate : APNSeq.T; VAR unknown : APNSeq.T; includePkgName := FALSE) RAISES {E}; (* Return lists of all files in the packages sorted by their version control status, i.e. modified, needing update etc. *) (*----------------------------------------------------------------------*) (* Support for Package States and Labels *) (*----------------------------------------------------------------------*) (* Packages may be labelled by an arbitrary text. This feature is used to record the quality state of the package as e.g. Exp (experimental, CVS default), buggy (contains known non-too-serious bugs), broken (contains serious bugs and must not be used), or approved (released for use by quality control). *) (*----------------------------------------------------------------------*) stateLabels() : TextTextTbl.T RAISES {E}; (* Return a mapping from all known tags to state labels. *) (*----------------------------------------------------------------------*) stateLabel(tag : Tag.T := NIL) : TEXT RAISES {E}; (* Return the state label for `tag'. If `tag' = NIL, the currently checked out state is assumed. *) (*----------------------------------------------------------------------*) setLabel(tag : Tag.T; label : TEXT; msg := NIL) RAISES {E}; (* Set the state label for version `tag' of the package to `label'. Record the setting in the log file for the package. If `msg' is NIL, just add date and user of the event. *) (*----------------------------------------------------------------------*) labelLog() : TEXT RAISES {E}; (* Get all log messages about changes of state labels for this package. *) END; (* Public *) VAR VC : T; confirmation : ConfirmClosure; END PkgVC.