1N/A# This program is free software; you can redistribute it and/or modify 1N/A# it under the terms of the GNU General Public License version 2 1N/A# as published by the Free Software Foundation. 1N/A# This program is distributed in the hope that it will be useful, 1N/A# but WITHOUT ANY WARRANTY; without even the implied warranty of 1N/A# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1N/A# GNU General Public License for more details. 1N/A# You should have received a copy of the GNU General Public License 1N/A# along with this program; if not, write to the Free Software 1N/A# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2N/A# Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. 1N/A# Copyright 2008, 2010 Richard Lowe 1N/A'''OpenSolaris extensions to Mercurial 1N/A This extension contains a number of commands to help you work with 1N/Athe OpenSolaris consolidations. It provides commands to check your 1N/Achanges against the various style rules used for OpenSolaris, to 1N/Abackup and restore your changes, to generate code reviews, and to 1N/Aprepare your changes for integration. 1N/A To provide a uniform notion of parent workspace regardless of 1N/Afilesystem-based access, Cadmium uses the highest numbered changeset 1N/Aon the current branch that is also in the parent workspace to 1N/Arepresent the parent workspace. 1N/A Many Cadmium commands operate on the active list, the set of 1N/Afiles ('active files') you have changed in this workspace in relation 1N/Ato its parent workspace, and the metadata (commentary, primarily) 1N/Aassociated with those changes. 1N/A Many of Cadmium's commands to check that your work obeys the 1N/Avarious stylistic rules of the OpenSolaris consolidations (such as 1N/Athose run by 'hg nits') allow files to be excluded from this checking 1N/Aby means of NOT files kept in the .hg/cdm/ directory of the Mercurial 1N/Arepository for one-time exceptions, and in the exception_lists 1N/Adirectory at the repository root for permanent exceptions. (For ON, 1N/Athese would mean one in $CODEMGR_WS and one in 1N/A These files are in the same format as the Mercurial hgignore 1N/Afile, a description of which is available in the hgignore(5) manual 1N/A - Show diffs relative to parent workspace - pdiffs 1N/A - Check source style rules - nits 1N/A - Run pre-integration checks - pbchk 1N/A - Collapse all your changes into a single changeset - recommit 1N/A# Adjust the load path based on the location of cdm.py and the version 1N/A# of python into which it is being loaded. This assumes the normal 1N/A# onbld directory structure, where cdm.py is in 1N/A# This and the case below are not equivalent. In this case we may be 1N/A# python2.Y in sys.path. 1N/A# such that a cdm.py loaded from the source tree uses the modules also 1N/A# within the source tree. 1N/A '''Build a list of files in which we're interested. 1N/A If no files are specified take files from the active list relative 1N/A Return a list of 2-tuples the first element being a path relative 1N/A to the current directory and the second an entry from the active 1N/A list, or None if an explicit file list was given.''' 1N/A '''return a function which returns boolean indicating whether a file 1N/A should be skipped for CMD.''' 1N/A # The ignore routines need a canonical path to the file (relative to the 1N/A # repo root), whereas the check commands get paths relative to the cwd. 1N/A # Wrap our argument such that the path is canonified before it is checked. 1N/A '''Abort if the workspace has uncommitted changes, merges, 1N/A branches, or has Mq patches applied''' 1N/A# Adding a reference to WorkSpace from a repo causes a circular reference 1N/A# repo <-> WorkSpace. 1N/A# This prevents repo, WorkSpace and members thereof from being garbage 1N/A# collected. Since transactions are aborted when the transaction object 1N/A# is collected, and localrepo holds a reference to the most recently created 1N/A# transaction, this prevents transactions from cleanly aborting. 1N/A# Instead, we hold the repo->WorkSpace association in a dictionary, breaking 1N/A 'python:hgext_cdm.pbconfirm')
1N/A '''diff workspace against its parent 1N/A Show differences between this workspace and its parent workspace 1N/A in the same manner as 'hg diff'. 1N/A For a description of the changeset used to represent the parent 1N/A workspace, see The Parent in the extension documentation ('hg help 1N/A '''list active files (those changed in this workspace) 1N/A Display a list of files changed in this workspace as compared to 1N/A its parent workspace. 1N/A File names are displayed one-per line, grouped by manner in which 1N/A they changed (added, modified, removed). Information about 1N/A renames or copies is output in parentheses following the file 1N/A For a description of the changeset used to represent the parent 1N/A workspace, see The Parent in the extension documentation ('hg help 1N/A Output can be filtered by change type with --added, --modified, 1N/A and --removed. By default, all files are shown. 1N/A '''show all ARC cases referenced in changeset comments''' 1N/A # We take a set of the appropriate comments to eliminate duplicates. 1N/A '''show all bug IDs referenced in changeset comments''' 1N/A '''show changeset commentary for all active changesets''' 1N/A '''show renamed active files 1N/A Renamed files are shown in the format:: 1N/A '''check active changeset comment formatting 1N/A Check that active changeset comments conform to O/N rules. 1N/A Each comment line must contain either one bug or ARC case ID 1N/A followed by its synopsis, or credit an external contributor. 1N/A '''check for a valid CDDL header comment in all active files. 1N/A Check active files for a valid Common Development and Distribution 1N/A License (CDDL) block comment. 1N/A Newly added files are checked for a copy of the CDDL header 1N/A comment. Modified files are only checked if they contain what 1N/A appears to be an existing CDDL header comment. 1N/A Files can be excluded from this check using the cddlchk.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A '''check for a valid mapfile header block in active files 1N/A Check that all link-editor mapfiles contain the standard mapfile 1N/A header comment directing the reader to the document containing 1N/A Solaris object versioning rules (README.mapfile). 1N/A Files can be excluded from this check using the mapfilechk.NOT 1N/A file. See NOT Files in the extension documentation ('hg help 1N/A # We are interested in examining any file that has the following 1N/A # in its final path segment: 1N/A # - Contains the word 'mapfile' 1N/A # - Begins with 'map.' 1N/A # - Ends with '.map' 1N/A # We don't want to match unless these things occur in final path segment 1N/A # because directory names with these strings don't indicate a mapfile. 1N/A # We also ignore files with suffixes that tell us that the files 1N/A '''check each active file for a current and correct copyright notice 1N/A Check that all active files have a correctly formed copyright 1N/A notice containing the current year. 1N/A See the Non-Formatting Considerations section of the OpenSolaris 1N/A Developer's Reference for more info on the correct form of 1N/A Files can be excluded from this check using the copyright.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A '''check active C header files conform to the O/N header rules 1N/A Check that any added or modified C header files conform to the O/N 1N/A See the section 'HEADER STANDARDS' in the hdrchk(1) manual page 1N/A for more information on the rules for O/N header file formatting. 1N/A Files can be excluded from this check using the hdrchk.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A '''check active C source files conform to the C Style Guide 1N/A Check that any added or modified C source file conform to the C 1N/A See the C Style Guide for more information about correct C source 1N/A Files can be excluded from this check using the cstyle.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A '''check active Java source files for common stylistic errors 1N/A Files can be excluded from this check using the jstyle.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A '''check the permissions of each active file 1N/A Check that the file permissions of each added or modified file do not 1N/A contain the executable bit. 1N/A Files can be excluded from this check using the permchk.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A ui.
write(
'Warning: the following active file(s) have executable mode ' 1N/A '(+x) permission set,\nremove unless intentional:\n')
1N/A '''check modification of workspace tags 1N/A Check for any modification of the repository's .hgtags file. 1N/A With the exception of the gatekeepers, nobody should introduce or 1N/A modify a repository's tags. 1N/A ui.
write(
'Warning: Workspace contains new non-local tags.\n' 1N/A 'Only gatekeepers should add or modify such tags.\n' 1N/A 'Use the following commands to revert these changes:\n' 1N/A ' hg revert -r%d %s\n' 1N/A 'You should also recommit before integration\n' %
1N/A '''check for changes in number or name of branches 1N/A Check that the workspace contains only a single head, that it is 1N/A on the branch 'default', and that no new branches have been 1N/A ui.
write(
'Checking for multiple heads (or branches):\n')
1N/A # We care if there's more than one head, and those heads aren't 1N/A # identical to the dirstate parents (if they are identical, it's 1N/A # an uncommitted merge which mergechk will catch, no need to 1N/A ui.
write(
'Workspace has multiple heads (or branches):\n')
1N/A ui.
write(
"Warning: Workspace tip has named branch: '%s'\n" 1N/A "Only gatekeepers should push new branches.\n" 1N/A "Use the following commands to restore the branch name:\n" 1N/A " hg branch [-f] default\n" 1N/A "You should also recommit before integration\n" %
1N/A ui.
write(
'Warning: Workspace has named branches:\n')
1N/A ui.
write(
"Only gatekeepers should push new branches.\n" 1N/A "Use the following commands to remove extraneous branches.\n" 1N/A " hg branch [-f] default\n" 1N/A "You should also recommit before integration\n")
1N/A Check that any CR IDs mentioned in active changeset comments have 1N/A an associated, approved Request to Integrate (RTI). 1N/A This check only works on systems with access to webrti.us.oracle.com. 1N/A This check maybe disabled by creating an empty file rtichk.NOT. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A ui.
write(
'RTI checks only work on SWAN, skipping...\n')
1N/A # RTI normalizes the gate path for us 1N/A '''check active files for SCCS keywords 1N/A Check that any added or modified files do not contain SCCS keywords 1N/A (#ident lines, etc.). 1N/A Files can be excluded from this check using the keywords.NOT file. 1N/A See NOT Files in the extension documentation ('hg help cdm'). 1N/A# There's no reason to hook this up as an invokable command, since 1N/A# we have 'hg status', but it must accept the same arguments. 1N/A '''Warn the user if they have uncommitted changes''' 1N/A ui.
write(
'Warning: the following files have uncommitted changes:\n')
1N/A '''Warn the user if their workspace contains merges''' 1N/A ui.
write(
'Workspace contains the following merges:\n')
1N/A '''Run CMDS (with OPTS) over active files in WS''' 1N/A '''check for stylistic nits in active files 1N/A Check each active file for basic stylistic errors. 1N/A The following checks are run over each active file (see 'hg help 1N/A <check>' for more information about each): 1N/A - cddlchk (CDDL block comments) 1N/A - copyright (copyright statements) 1N/A - cstyle (C source style) 1N/A - hdrchk (C header style) 1N/A - jstyle (java source style) 1N/A - mapfilechk (link-editor mapfiles) 1N/A - permchk (file permissions) 1N/A - keywords (SCCS keywords) 1N/A With the global -q/--quiet option, only provide output for those 1N/A '''run pre-integration checks on this workspace 1N/A Check this workspace for common errors prior to integration. 1N/A The following checks are run over the active list (see 'hg help 1N/A <check>' for more information about each): 1N/A - cddlchk (CDDL block comments) 1N/A - comchk (changeset descriptions) 1N/A - copyright (copyright statements) 1N/A - cstyle (C source style) 1N/A - hdrchk (C header style) 1N/A - jstyle (java source style) 1N/A - keywords (SCCS keywords) 1N/A - mapfilechk (link-editor mapfiles) 1N/A - permchk (file permissions) 1N/A - rtichk (requests to integrate) 1N/A Additionally, the workspace is checked for outgoing merges (which 1N/A should be removed with 'hg recommit'), and uncommitted changes. 1N/A With the global -q/--quiet option, only provide output for those 1N/A # The current ordering of these is that the commands from cdm_nits 1N/A # run first in the same order as they would in cdm_nits, then the 1N/A # pbchk specifics are run. 1N/A '''replace outgoing changesets with a single equivalent changeset 1N/A Replace all outgoing changesets with a single changeset containing 1N/A equivalent changes. This removes uninteresting changesets created 1N/A during development that would only serve as noise in the gate. 1N/A Any changed file that is now identical in content to that in the 1N/A parent workspace (whether identical in history or otherwise) will 1N/A not be included in the new changeset. Any merges information will 1N/A If no files are changed in comparison to the parent workspace, the 1N/A outgoing changesets will be removed, but no new changeset created. 1N/A recommit will refuse to run if the workspace contains more than 1N/A one outgoing head, even if those heads are on the same branch. To 1N/A recommit with only one branch containing outgoing changesets, your 1N/A workspace must be on that branch and at that branch head. 1N/A recommit will prompt you to take a backup if your workspace has 1N/A been changed since the last backup was taken. In almost all 1N/A cases, you should allow it to take one (the default). 1N/A recommit cannot be run if the workspace contains any uncommitted 1N/A changes, applied Mq patches, or has multiple outgoing heads (or 1N/A ui.
warn(
'Workspace has multiple outgoing heads (or branches):\n')
1N/A raise util.
Abort(
'Cannot recommit a merge of two non-outgoing ' 1N/A ui.
warn(
"Recommitting %d active changesets, but no active files\n" %
1N/A # During the course of a recommit, any file bearing a name 1N/A # matching the source name of any renamed file will be 1N/A # clobbered by the operation. 1N/A # As such, we ask the user before proceeding. 1N/A ui.
warn(
"The following file names are the original name of a " 1N/A "rename and also present\n" 1N/A "in the working directory:\n")
1N/A if not yes_no(
ui,
"These files will be removed by recommit." 1N/A ui.
write(
"tag '%s' now refers to revision %d:%s\n" %
1N/A '''run specified command for each active file 1N/A Run the command specified on the command line for each active 1N/A file, with the following variables present in the environment: 1N/A :$file: - active file basename. 1N/A :$dir: - active file dirname. 1N/A :$filepath: - path from workspace root to active file. 1N/A :$workspace: - full path to workspace root. 1N/A hg eval 'echo $dir; hg log -l3 $file' 1N/A will show the last the 3 log entries for each active file, 1N/A preceded by its directory. 1N/A '''apply specified command to all active files 1N/A Run the command specified on the command line over each active 1N/A For example 'hg apply "wc -l"' will output a count of the lines in 1N/A raise util.
Abort(
'Failed to open workspace configuration: %s' % e)
2N/A # In 1.9 (changeset d764463b433e in the mercurial repo), atomictempfile() 2N/A # stopped delegating all undefined methods to file() using __getattr__(), so 2N/A # use of "closed" and "tell" now raise an exception. Then in 2.0 (changeset 2N/A # 774da7121fc9), rename() got renamed to close() and close() got renamed to 2N/A # discard(). Hence the ugliness. 1N/A line =
line -
1 # The line number we're passed will be 1-based 1N/A # line will be the last line of any continued block, go back 1N/A # to the first removing the continuation as we go. 1N/A raise util.
Abort(
"Cannot edit path specification not in repo hgrc\n" 1N/A Update the 'default' path alias that is used as the default source 1N/A for 'hg pull' and the default destination for 'hg push' (unless 1N/A there is a 'default-push' alias). This is also the path all 1N/A Cadmium commands treat as your parent workspace. 1N/A '''Create a backup directory name based on the specified path. 1N/A In most cases this is the basename of the path specified, but 1N/A certain cases are handled specially to create meaningful names''' 1N/A # If a path is 'special', we append the basename of the path to 1N/A # the path element preceding the constant, special, part. 1N/A # Such that for instance: 1N/A # has a backup name of: 1N/A '''backup workspace changes and metadata 1N/A Create a backup copy of changes made in this workspace as compared 1N/A to its parent workspace, as well as important metadata of this 1N/A NOTE: Only changes as compared to the parent workspace are backed 1N/A up. If you lose this workspace and its parent, you will not be 1N/A able to restore a backup into a clone of the grandparent 1N/A By default, backups are stored in the cdm.backup/ directory in 1N/A your home directory. This is configurable using the cdm.backupdir 1N/A configuration variable, for example: 1N/A or place the following in an appropriate hgrc file:: 1N/A Backups have the same name as the workspace in which they were 1N/A taken, with '-closed' appended in the case of O/N's usr/closed. 1N/A '''restore workspace from backup 1N/A Restore this workspace from a backup (taken by 'hg backup'). 1N/A If the specified backup directory does not exist, it is assumed to 1N/A be relative to the cadmium backup directory (~/cdm.backup/ by 1N/A '''generate web-based code review and optionally upload it 1N/A Generate a web-based code review using webrev(1) and optionally 1N/A upload it. All known arguments are passed through to webrev(1). 1N/A 'apply': (
cdm_apply, [(
'p',
'parent',
'',
'parent workspace'),
1N/A (
'r',
'remain',
None,
'do not change directory')],
1N/A 'hg apply [-p PARENT] [-r] command...'),
1N/A 'arcs': (
cdm_arcs, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg arcs [-p PARENT]'),
1N/A 'only backup if workspace files are newer')],
1N/A 'hg branchchk [-p PARENT]'),
1N/A 'bugs': (
cdm_bugs, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg bugs [-p PARENT]'),
1N/A 'hg cddlchk [-p PARENT]'),
1N/A (
'N',
'nocheck',
None,
1N/A 'do not compare comments with databases')],
1N/A 'hg comchk [-p PARENT]'),
1N/A 'hg comments [-p PARENT]'),
1N/A 'hg copyright [-p PARENT]'),
1N/A 'cstyle': (
cdm_cstyle, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg cstyle [-p PARENT]'),
1N/A 'eval': (
cdm_eval, [(
'p',
'parent',
'',
'parent workspace'),
1N/A (
'r',
'remain',
None,
'do not change directory')],
1N/A 'hg eval [-p PARENT] [-r] command...'),
1N/A 'hdrchk': (
cdm_hdrchk, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg hdrchk [-p PARENT]'),
1N/A 'jstyle': (
cdm_jstyle, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg jstyle [-p PARENT]'),
1N/A 'hg keywords [-p PARENT]'),
1N/A '^list|active': (
cdm_list, [(
'p',
'parent',
'',
'parent workspace'),
1N/A (
'a',
'added',
None,
'show added files'),
1N/A (
'm',
'modified',
None,
'show modified files'),
1N/A (
'r',
'removed',
None,
'show removed files')],
1N/A 'hg list [-amrRu] [-p PARENT]'),
1N/A 'hg mapfilechk [-p PARENT]'),
1N/A '^nits': (
cdm_nits, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg nits [-p PARENT]'),
1N/A '^pbchk': (
cdm_pbchk, [(
'p',
'parent',
'',
'parent workspace'),
1N/A (
'N',
'nocheck',
None,
1N/A 'hg pbchk [-N] [-p PARENT]'),
1N/A 'hg permchk [-p PARENT]'),
1N/A '^pdiffs': (
cdm_pdiffs, [(
'p',
'parent',
'',
'parent workspace'),
1N/A (
'a',
'text',
None,
'treat all files as text'),
1N/A (
'g',
'git',
None,
'use extended git diff format'),
1N/A (
'w',
'ignore-all-space',
None,
1N/A 'ignore white space when comparing lines'),
1N/A (
'b',
'ignore-space-change',
None,
1N/A 'ignore changes in the amount of white space'),
1N/A (
'B',
'ignore-blank-lines',
None,
1N/A 'ignore changes whose lines are all blank'),
1N/A 'number of lines of context to show'),
1N/A (
'I',
'include', [],
1N/A 'include names matching the given patterns'),
1N/A (
'X',
'exclude', [],
1N/A 'exclude names matching the given patterns')],
1N/A 'hg pdiffs [OPTION...] [-p PARENT] [FILE...]'),
1N/A (
'm',
'message',
'',
1N/A 'use <text> as commit message'),
1N/A (
'l',
'logfile',
'',
1N/A 'read commit message from file'),
1N/A 'record user as committer')],
1N/A 'hg recommit [-m TEXT] [-l FILE] [-u USER] [-p PARENT]'),
1N/A 'hg renamed [-p PARENT]'),
1N/A '^restore': (
cdm_restore, [(
'g',
'generation',
'',
'generation number')],
1N/A 'hg restore [-g GENERATION] BACKUP'),
1N/A (
'N',
'nocheck',
None,
'skip RTI check')],
1N/A 'hg rtichk [-N] [-p PARENT]'),
1N/A 'tagchk': (
cdm_tagchk, [(
'p',
'parent',
'',
'parent workspace')],
1N/A 'hg tagchk [-p PARENT]'),
1N/A (
'D',
'D',
None,
'delete remote webrev'),
1N/A (
'I',
'I',
'',
'ITS configuration file'),
1N/A (
'i',
'i',
'',
'include file'),
1N/A (
'N',
'N',
None,
'suppress comments'),
1N/A (
'n',
'n',
None,
'do not generate webrev'),
1N/A (
'O',
'O',
None,
'OpenSolaris mode'),
1N/A (
'o',
'o',
'',
'output directory'),
1N/A (
'p',
'p',
'',
'use specified parent'),
1N/A (
't',
't',
'',
'upload target'),
1N/A (
'U',
'U',
None,
'upload the webrev'),
1N/A (
'w',
'w',
'',
'use wx active file'),
1N/A (
'z',
'z',
None,
'compress the webrev in ZIP format')],
1N/A 'hg webrev [WEBREV_OPTIONS]'),