cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This program is free software; you can redistribute it and/or modify
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# it under the terms of the GNU General Public License version 2
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# as published by the Free Software Foundation.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This program is distributed in the hope that it will be useful,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# but WITHOUT ANY WARRANTY; without even the implied warranty of
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# GNU General Public License for more details.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# You should have received a copy of the GNU General Public License
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# along with this program; if not, write to the Free Software
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe# Copyright 2008, 2011 Richard Lowe
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore# Copyright 2014 Garrett D'Amore <garrett@damore.org>
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulow# Copyright (c) 2014, Joyent, Inc.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe'''OpenSolaris extensions to Mercurial
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe This extension contains a number of commands to help you work with
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethe OpenSolaris consolidations. It provides commands to check your
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowechanges against the various style rules used for OpenSolaris, to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowebackup and restore your changes, to generate code reviews, and to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweprepare your changes for integration.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe To provide a uniform notion of parent workspace regardless of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefilesystem-based access, Cadmium uses the highest numbered changeset
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweon the current branch that is also in the parent workspace to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowerepresent the parent workspace.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard LoweThe Active List
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Many Cadmium commands operate on the active list, the set of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefiles ('active files') you have changed in this workspace in relation
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweto its parent workspace, and the metadata (commentary, primarily)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweassociated with those changes.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Many of Cadmium's commands to check that your work obeys the
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowevarious stylistic rules of the OpenSolaris consolidations (such as
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethose run by 'hg nits') allow files to be excluded from this checking
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Loweby means of NOT files kept in the .hg/cdm/ directory of the Mercurial
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowerepository for one-time exceptions, and in the exception_lists
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowedirectory at the repository root for permanent exceptions. (For ON,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowethese would mean one in $CODEMGR_WS and one in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe These files are in the same format as the Mercurial hgignore
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowefile, a description of which is available in the hgignore(5) manual
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Show diffs relative to parent workspace - pdiffs
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Check source style rules - nits
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Run pre-integration checks - pbchk
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - Collapse all your changes into a single changeset - recommit
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Adjust the load path based on the location of cdm.py and the version
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# of python into which it is being loaded. This assumes the normal
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# onbld directory structure, where cdm.py is in
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# lib/python(version)?/onbld/hgext/. If that changes so too must
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# This and the case below are not equivalent. In this case we may be
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# loading a cdm.py in python2.X/ via the lib/python/ symlink but need
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# python2.Y in sys.path.
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowesys.path.insert(1, os.path.join(os.path.dirname(__file__), "..", "..", "..",
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# Add the relative path from cdm.py to usr/src/tools to the load path,
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# such that a cdm.py loaded from the source tree uses the modules also
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowe# within the source tree.
87ab362234f761757d96ff1a758ab5c3bd85ed83Richard Lowesys.path.insert(2, os.path.join(os.path.dirname(__file__), "..", ".."))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort("Version Mismatch:\n %s\n" % badversion)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowefrom onbld.Scm.WorkSpace import WorkSpace, WorkList
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom onbld.Checks import Cddl, Comments, Copyright, CStyle, HdrChk
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amorefrom onbld.Checks import JStyle, Keywords, ManLint, Mapfile
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe index = ui.promptchoice(msg + prompt, ['&yes', '&no'],
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe resp = ui.prompt(msg + prompt, ['&yes', '&no'], default=defanswer)
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe '''Build a list of files in which we're interested.
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe If no files are specified take files from the active list relative
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe to 'parent'.
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe Return a list of 2-tuples the first element being a path relative
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe to the current directory and the second an entry from the active
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe list, or None if an explicit file list was given.'''
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe return [(path, None) for path in sorted(files)]
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe return [(ws.filepath(e.name), e) for e in sorted(active)]
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson '''return a function which returns boolean indicating whether a file
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson should be skipped for CMD.'''
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # The ignore routines need a canonical path to the file (relative to the
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # repo root), whereas the check commands get paths relative to the cwd.
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami # Wrap our argument such that the path is canonified before it is checked.
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami cpath = util.canonpath(repo.root, repo.getcwd(), path)
e55874358132a4aa6132178335bf567ca79c87c3Joshua M. Clulow ign = Ignore.ignore(repo.root, ignorefiles)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe '''Abort if the workspace has uncommitted changes, merges,
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe branches, or has Mq patches applied'''
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace has uncommitted changes')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace contains uncommitted merge')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace contains uncommitted branch')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort('workspace has Mq patches applied')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Adding a reference to WorkSpace from a repo causes a circular reference
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# repo <-> WorkSpace.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# This prevents repo, WorkSpace and members thereof from being garbage
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# collected. Since transactions are aborted when the transaction object
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# is collected, and localrepo holds a reference to the most recently created
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# transaction, this prevents transactions from cleanly aborting.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Instead, we hold the repo->WorkSpace association in a dictionary, breaking
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# that dependence.
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe ui.setconfig('hooks', 'preoutgoing.cdm_pbconfirm',
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe 'python:hgext_cdm.pbconfirm')
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, settings)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson if not yes_no(ui, "Are you sure you wish to push?", False):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson settings = termios.tcgetattr(sys.stdin.fileno())
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe settings[3] = settings[3] & (~termios.ISIG) # c_lflag
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, settings)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''diff workspace against its parent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Show differences between this workspace and its parent workspace
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe in the same manner as 'hg diff'.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For a description of the changeset used to represent the parent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace, see The Parent in the extension documentation ('hg help
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # If no patterns were specified, either explicitly or via -I or -X
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # use the active list files to avoid a workspace walk.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if pats or opts.get('include') or opts.get('exclude'):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe matchfunc = wslist[repo].matcher(pats=pats, opts=opts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe matchfunc = wslist[repo].matcher(files=act.files())
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe diffs = wslist[repo].diff(act.parenttip.node(), act.localtip.node(),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''list active files (those changed in this workspace)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Display a list of files changed in this workspace as compared to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe its parent workspace.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe File names are displayed one-per line, grouped by manner in which
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe they changed (added, modified, removed). Information about
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe renames or copies is output in parentheses following the file
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For a description of the changeset used to represent the parent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe workspace, see The Parent in the extension documentation ('hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Output can be filtered by change type with --added, --modified,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe and --removed. By default, all files are shown.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe wanted = set(x for x in ('added', 'modified', 'removed') if opts[x])
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write('\t%s (renamed from %s)\n' % (entry.name,
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write('\t%s (copied from %s)\n' % (entry.name,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''show all bug IDs referenced in changeset comments'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for elt in set(filter(Comments.isBug, act.comments())):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''show changeset commentary for all active changesets'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''show renamed active files
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Renamed files are shown in the format::
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe new-name old-name
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe One pair per-line.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for entry in sorted(filter(lambda x: x.is_renamed(), act)):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('%s %s\n' % (entry.name, entry.parentname))
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active changeset comment formatting
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that active changeset comments conform to O/N rules.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Each comment line must contain either one bug or ARC case ID
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe followed by its synopsis, or credit an external contributor.
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe return Comments.comchk(active.comments(), check_db=check_db, output=ui)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for a valid CDDL header comment in all active files.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check active files for a valid Common Development and Distribution
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe License (CDDL) block comment.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Newly added files are checked for a copy of the CDDL header
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe comment. Modified files are only checked if they contain what
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe appears to be an existing CDDL header comment.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the cddlchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif e and e.is_added():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret |= Cddl.cddlchk(fh, lenient=lenient, output=ui)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore '''check for mandoc lint
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Check for man page formatting errors.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore Files can be excluded from this check using the manlint.NOT
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore file. See NOT Files in the extension documentation ('hg help
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore # Man pages are identified as having a suffix starting with a digit.
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ManfileRE = re.compile(r'.*\.[0-9][a-z]*$', re.IGNORECASE)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore elif (e or opts.get('honour_nots')) and exclude(f):
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore ret |= ManLint.manlint(fh, output=ui, picky=True)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for a valid mapfile header block in active files
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami Check that all link-editor mapfiles contain the standard mapfile
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami header comment directing the reader to the document containing
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Solaris object versioning rules (README.mapfile).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the mapfilechk.NOT
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe file. See NOT Files in the extension documentation ('hg help
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # We are interested in examining any file that has the following
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # in its final path segment:
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Contains the word 'mapfile'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Begins with 'map.'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # - Ends with '.map'
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # We don't want to match unless these things occur in final path segment
cd3e933325e68e23516a196a8fea7f49b1e497c3Ali Bahrami # because directory names with these strings don't indicate a mapfile.
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami # We also ignore files with suffixes that tell us that the files
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami # are not mapfiles.
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami MapfileRE = re.compile(r'.*((mapfile[^/]*)|(/map\.+[^/]*)|(\.map))$',
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami NotMapSuffixRE = re.compile(r'.*\.[ch]$', re.IGNORECASE)
d24e1a1da37e9f5e4c5b11a5da612fdd70d873f0Ali Bahrami elif (not MapfileRE.match(f)) or NotMapSuffixRE.match(f):
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami elif (e or opts.get('honour_nots')) and exclude(f):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check each active file for a current and correct copyright notice
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that all active files have a correctly formed copyright
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe notice containing the current year.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the Non-Formatting Considerations section of the OpenSolaris
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Developer's Reference for more info on the correct form of
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe copyright notice.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (http://hub.opensolaris.org/bin/view/Community+Group+on/devref_7#H723NonFormattingConsiderations)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the copyright.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active C header files conform to the O/N header rules
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified C header files conform to the O/N
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe header rules.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the section 'HEADER STANDARDS' in the hdrchk(1) manual page
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe for more information on the rules for O/N header file formatting.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the hdrchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ret |= HdrChk.hdrchk(fh, lenient=True, output=ui)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''check active C source files conform to the C Style Guide
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified C source file conform to the C
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Style Guide.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See the C Style Guide for more information about correct C source
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (http://hub.opensolaris.org/bin/download/Community+Group+on/WebHome/cstyle.ms.pdf)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the cstyle.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif not (f.endswith('.c') or f.endswith('.h')):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active Java source files for common stylistic errors
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the jstyle.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ret |= JStyle.jstyle(fh, output=ui, picky=True)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check the permissions of each active file
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that the file permissions of each added or modified file do not
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe contain the executable bit.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the permchk.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson mode = stat.S_IMODE(os.stat(f)[stat.ST_MODE])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: the following active file(s) have executable mode '
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '(+x) permission set,\nremove unless intentional:\n')
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check modification of workspace tags
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check for any modification of the repository's .hgtags file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the exception of the gatekeepers, nobody should introduce or
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe modify a repository's tags.
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: Workspace contains new non-local tags.\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'Only gatekeepers should add or modify such tags.\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'Use the following commands to revert these changes:\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ' hg revert -r%d %s\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ' hg commit %s\n'
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'You should also recommit before integration\n' %
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check for changes in number or name of branches
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that the workspace contains only a single head, that it is
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe on the branch 'default', and that no new branches have been
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Checking for multiple heads (or branches):\n')
2b5878de2735cb61d008168e1f27e390d2edf915Rich Lowe parents = set([x.node() for x in wslist[repo].workingctx().parents()])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # We care if there's more than one head, and those heads aren't
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # identical to the dirstate parents (if they are identical, it's
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # an uncommitted merge which mergechk will catch, no need to
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # complain twice).
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Workspace has multiple heads (or branches):\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for head in [repo.changectx(head) for head in heads]:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson (head.rev(), str(head), head.description().splitlines()[0]))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("Warning: Workspace tip has named branch: '%s'\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Only gatekeepers should push new branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Use the following commands to restore the branch name:\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg branch [-f] default\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg commit\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "You should also recommit before integration\n" %
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: Workspace has named branches:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if t == 'default':
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write("Only gatekeepers should push new branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "Use the following commands to remove extraneous branches.\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg branch [-f] default\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson " hg commit"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "You should also recommit before integration\n")
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''check active files for SCCS keywords
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check that any added or modified files do not contain SCCS keywords
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe (#ident lines, etc.).
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Files can be excluded from this check using the keywords.NOT file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe See NOT Files in the extension documentation ('hg help cdm').
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe filelist = buildfilelist(wslist[repo], opts.get('parent'), args)
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson elif (e or opts.get('honour_nots')) and exclude(f):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# There's no reason to hook this up as an invokable command, since
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# we have 'hg status', but it must accept the same arguments.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Warn the user if they have uncommitted changes'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Warning: the following files have uncommitted changes:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Warn the user if their workspace contains merges'''
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson active = wslist[repo].active(opts.get('parent'))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson merges = filter(lambda x: len(x.parents()) == 2 and x.parents()[1],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ui.write('Workspace contains the following merges:\n')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Run CMDS (with OPTS) over active files in WS'''
0df7087fda4bb16f7e1cf07d1b90fcf070c19484Richard Lowe result = cmd(ws.ui, ws.repo, honour_nots=True, *args, **opts)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''check for stylistic nits in active files
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check each active file for basic stylistic errors.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe The following checks are run over each active file (see 'hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe <check>' for more information about each):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - copyright (copyright statements)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - cstyle (C source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - hdrchk (C header style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - jstyle (java source style)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore - manlint (man page formatting)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - mapfilechk (link-editor mapfiles)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - permchk (file permissions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - keywords (SCCS keywords)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the global -q/--quiet option, only provide output for those
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe checks which fail.
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson return run_checks(wslist[repo], cmds, *args, **opts)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''run pre-integration checks on this workspace
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Check this workspace for common errors prior to integration.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe The following checks are run over the active list (see 'hg help
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe <check>' for more information about each):
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - branchchk (addition/modification of branches)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - comchk (changeset descriptions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - copyright (copyright statements)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - cstyle (C source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - hdrchk (C header style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - jstyle (java source style)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - keywords (SCCS keywords)
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore - manlint (man page formatting)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - mapfilechk (link-editor mapfiles)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - permchk (file permissions)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe - tagchk (addition/modification of tags)
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Additionally, the workspace is checked for outgoing merges (which
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe should be removed with 'hg recommit'), and uncommitted changes.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe With the global -q/--quiet option, only provide output for those
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe checks which fail.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # The current ordering of these is that the commands from cdm_nits
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe # run first in the same order as they would in cdm_nits, then the
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe # pbchk specifics are run.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp '''replace outgoing changesets with a single equivalent changeset
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp Replace all outgoing changesets with a single changeset containing
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp equivalent changes. This removes uninteresting changesets created
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp during development that would only serve as noise in the gate.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp Any changed file that is now identical in content to that in the
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp parent workspace (whether identical in history or otherwise) will
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp not be included in the new changeset. Any merges information will
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp also be removed.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp If no files are changed in comparison to the parent workspace, the
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp outgoing changesets will be removed, but no new changeset created.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit will refuse to run if the workspace contains more than
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp one outgoing head, even if those heads are on the same branch. To
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit with only one branch containing outgoing changesets, your
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp workspace must be on that branch and at that branch head.
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit will prompt you to take a backup if your workspace has
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp been changed since the last backup was taken. In almost all
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp cases, you should allow it to take one (the default).
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp recommit cannot be run if the workspace contains any uncommitted
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp changes, applied Mq patches, or has multiple outgoing heads (or
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp branches).
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort('recommit is not safe to run with -R')
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp between = repo.changelog.nodesbetween(ws.findoutgoing(parent))[2]
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp ui.warn('Workspace has multiple outgoing heads (or branches):\n')
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp for head in sorted(map(repo.changelog.rev, heads), reverse=True):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # We can safely use the worklist here, as we know (from the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # abort_if_dirty() check above) that the working copy has not been
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp if filter(lambda b: len(b.parents()) > 1, active.bases()):
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp raise util.Abort('Cannot recommit a merge of two non-outgoing '
c7f512e49da83ae2cd3d4b339e1a8366544471e2jmcp 'changesets')
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.warn("Recommitting %d active changesets, but no active files\n" %
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # During the course of a recommit, any file bearing a name
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # matching the source name of any renamed file will be
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # clobbered by the operation.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # As such, we ask the user before proceeding.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe bogosity = [f.parentname for f in active if f.is_renamed() and
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe ui.warn("The following file names are the original name of a "
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe "rename and also present\n"
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe "in the working directory:\n")
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if not yes_no(ui, "These files will be removed by recommit."
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe " Continue?",
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort("recommit would clobber files")
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe message = cmdutil.logmessage(opts) or ui.edit(comments, user)
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe if yes_no(ui, 'Do you want to backup files first?', True):
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe clearedtags = [(name, nd, repo.changelog.rev(nd), local)
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe ui.write(" %5s:%s:\t%s%s\n" % (rev, node.short(nd),
cf4134fe6ab2c92c4811c4af7dd391469c72bf73Rich Lowe ui.write("tag '%s' now refers to revision %d:%s\n" %
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''run specified command for each active file
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Run the command specified on the command line for each active
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe file, with the following variables present in the environment:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$file: - active file basename.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$dir: - active file dirname.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$filepath: - path from workspace root to active file.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe :$workspace: - full path to workspace root.
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe hg eval 'echo $dir; hg log -l3 $file'
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe will show the last the 3 log entries for each active file,
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe preceded by its directory.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson files = [x.name for x in act if not x.is_removed()]
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''apply specified command to all active files
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Run the command specified on the command line over each active
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example 'hg apply "wc -l"' will output a count of the lines in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe each active file.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson files = [x.name for x in act if not x.is_removed()]
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe '''reparent your workspace
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Update the 'default' path alias that is used as the default source
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe for 'hg pull' and the default destination for 'hg push' (unless
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe there is a 'default-push' alias). This is also the path all
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Cadmium commands treat as your parent workspace.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe line = line - 1 # The line number we're passed will be 1-based
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # line will be the last line of any continued block, go back
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe # to the first removing the continuation as we go.
c959a081a8aebb76386b6d8ea3afa850e328f6c7Richard Lowe raise util.Abort("Cannot edit path specification not in repo hgrc\n"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''Create a backup directory name based on the specified path.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson In most cases this is the basename of the path specified, but
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson certain cases are handled specially to create meaningful names'''
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson fullpath = fullpath.rstrip(os.path.sep).split(os.path.sep)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # If a path is 'special', we append the basename of the path to
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # the path element preceding the constant, special, part.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # Such that for instance:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # has a backup name of:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # onnv-fixes-closed
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''backup workspace changes and metadata
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Create a backup copy of changes made in this workspace as compared
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe to its parent workspace, as well as important metadata of this
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe NOTE: Only changes as compared to the parent workspace are backed
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe up. If you lose this workspace and its parent, you will not be
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe able to restore a backup into a clone of the grandparent
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe By default, backups are stored in the cdm.backup/ directory in
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe your home directory. This is configurable using the cdm.backupdir
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe configuration variable, for example:
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe hg backup --config cdm.backupdir=/net/foo/backups
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe or place the following in an appropriate hgrc file::
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Backups have the same name as the workspace in which they were
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe taken, with '-closed' appended in the case of O/N's usr/closed.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '''restore workspace from backup
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Restore this workspace from a backup (taken by 'hg backup').
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe If the specified backup directory does not exist, it is assumed to
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe be relative to the cadmium backup directory (~/cdm.backup/ by
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe For example::
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore on-rfe - Restore the latest backup of ~/cdm.backup/on-rfe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore -g3 on-rfe - Restore the 3rd backup of ~/cdm.backup/on-rfe
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe % hg restore /net/foo/backup/on-rfe - Restore from an explicit path
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson raise util.Abort('restore is not safe to run with -R')
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe '''generate web-based code review and optionally upload it
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe Generate a web-based code review using webrev(1) and optionally
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe upload it. All known arguments are passed through to webrev(1).
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe '''dump the active list for the sake of debugging/testing'''
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.write(wslist[repo].active(opts['parent']).as_text(pats))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe '''mark a file as changed in the working copy
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Maintain a list of files checked for modification in the working
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe copy. If the list exists, most cadmium commands will only check
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe the working copy for changes to those files, rather than checking
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe the whole workspace (this does not apply to committed changes,
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe which are always seen).
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Since this list functions only as a hint as to where in the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe working copy to look for changes, entries that have not actually
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe been modified (in the working copy, or in general) are not
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe problematic.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Note: If such a list exists, it must be kept up-to-date.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Renamed files can be added with reference only to their new name:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg mv foo bar
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed bar
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Without arguments, 'hg changed' will list all files recorded as
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe altered, such that, for instance:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg status $(hg changed)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg diff $(hg changed)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Become useful (generally faster than their unadorned counterparts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe To create an initially empty list:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -i
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Until files are added to the list it is equivalent to saying
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe "Nothing has been changed"
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Update the list based on the current active list:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -u
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe The old list is emptied, and replaced with paths from the
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe current active list.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe Remove the list entirely:
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe $ hg changed -d
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe out = wslist[repo].findoutgoing(wslist[repo].parent(parent))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # specced_pats is convenient to treat as a boolean indicating
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # whether any file patterns or paths were specified.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe specced_pats = pats or opts['include'] or opts['exclude']
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if len(filter(None, [opts['delete'], opts['update'], opts['init'],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe raise util.Abort("-d, -u, -i and patterns are mutually exclusive")
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe if yes_no(ui, "Create a list based on your changes thus far?", True):
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe map(wl.add, modded_files(repo, opts.get('parent')))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe map(wl.add, modded_files(repo, opts.get('parent')))
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe elif opts['init']: # Any possible old list was deleted above
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe match = wslist[repo].matcher(pats=pats, opts=opts)
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # Store the source name of any copy. We use this so
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # both the add and delete of a rename can be entered
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # into the WorkList with only the destination name
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe # explicitly being mentioned.
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ui.warn("%s is not version controlled -- skipping\n" %
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe for fname, chng in wslist[repo].status(files=sources).iteritems():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'apply': (cdm_apply, [('p', 'parent', '', 'parent workspace'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('r', 'remain', None, 'do not change directory')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg apply [-p PARENT] [-r] command...'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^backup|bu': (cdm_backup, [('t', 'if-newer', None,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'only backup if workspace files are newer')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg backup [-t]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'branchchk': (cdm_branchchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg branchchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'bugs': (cdm_bugs, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg bugs [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'cddlchk': (cdm_cddlchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg cddlchk [-p PARENT]'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'changed': (cdm_changed, [('d', 'delete', None, 'delete the file list'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('u', 'update', None, 'mark all changed files'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe ('i', 'init', None, 'create an empty file list'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'include names matching the given patterns'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'exclude names matching the given patterns')],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -d\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -u\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed -i\n'
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg changed [-I PATTERN...] [-X PATTERN...] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'comchk': (cdm_comchk, [('p', 'parent', '', 'parent workspace'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'do not compare comments with databases')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg comchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'comments': (cdm_comments, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg comments [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'copyright': (cdm_copyright, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg copyright [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'cstyle': (cdm_cstyle, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg cstyle [-p PARENT]'),
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'debugcdmal': (cdm_debugcdmal, [('p', 'parent', '', 'parent workspace')],
605a716e6d38b3af09034c254382d0ae3b7d5f70Richard Lowe 'hg debugcdmal [-p PARENT] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'eval': (cdm_eval, [('p', 'parent', '', 'parent workspace'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('r', 'remain', None, 'do not change directory')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg eval [-p PARENT] [-r] command...'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hdrchk': (cdm_hdrchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg hdrchk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'jstyle': (cdm_jstyle, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg jstyle [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'keywords': (cdm_keywords, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg keywords [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^list|active': (cdm_list, [('p', 'parent', '', 'parent workspace'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe ('m', 'modified', None, 'show modified files'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg list [-amrRu] [-p PARENT]'),
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore 'manlint': (cdm_manlintchk, [('p', 'parent', '', 'parent workspace')],
95c635efb7c3b86efc493e0447eaec7aecca3f0fGarrett D'Amore 'hg manlint [-p PARENT]'),
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami 'mapfilechk': (cdm_mapfilechk, [('p', 'parent', '', 'parent workspace')],
bfed486ad8de8b8ebc6345a8e10accae08bf2f45Ali Bahrami 'hg mapfilechk [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^nits': (cdm_nits, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg nits [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^pbchk': (cdm_pbchk, [('p', 'parent', '', 'parent workspace'),
2f54b716e4d3cb0dc99066638fed631e3cbec97cRichard Lowe ('N', 'nocheck', None, 'skip database checks')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg pbchk [-N] [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'permchk': (cdm_permchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg permchk [-p PARENT]'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson '^pdiffs': (cdm_pdiffs, [('p', 'parent', '', 'parent workspace'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('a', 'text', None, 'treat all files as text'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson ('g', 'git', None, 'use extended git diff format'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'ignore white space when comparing lines'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'ignore changes in the amount of white space'),
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe 'ignore changes whose lines are all blank'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'number of lines of context to show'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'include names matching the given patterns'),
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'exclude names matching the given patterns')],
9a70fc3be3b1e966bf78825cdb8d509963a6f0a1Mark J. Nelson 'hg pdiffs [OPTION...] [-p PARENT] [FILE...]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^recommit|reci': (cdm_recommit, [('p', 'parent', '', 'parent workspace'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'use <text> as commit message'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'read commit message from file'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'record user as committer')],
8703921742d9c7d4d3724f89a39ff0e2725cbe7bRichard Lowe 'hg recommit [-m TEXT] [-l FILE] [-u USER] [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'renamed': (cdm_renamed, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg renamed [-p PARENT]'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'reparent': (cdm_reparent, [], 'hg reparent PARENT'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson '^restore': (cdm_restore, [('g', 'generation', '', 'generation number')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg restore [-g GENERATION] BACKUP'),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'tagchk': (cdm_tagchk, [('p', 'parent', '', 'parent workspace')],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'hg tagchk [-p PARENT]'),
25cc4e45d2ae4f199cec8b3a58f01500f2db7815Vladimir Kotal 'webrev': (cdm_webrev, [('C', 'C', '', 'ITS priority file'),
02d26c39c38c50cee317dd3a02c320bbf1e5a099Vladimir Kotal 'hg webrev [WEBREV_OPTIONS]'),