-- Copyright (C) 2002-2004 David Roundy---- This program is free software; you can redistribute it and/or modify-- it under the terms of the GNU General Public License as published by-- the Free Software Foundation; either version 2, or (at your option)-- any later version.---- This program is distributed in the hope that it will be useful,-- but WITHOUT ANY WARRANTY; without even the implied warranty of-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-- GNU General Public License for more details.---- You should have received a copy of the GNU General Public License-- along with this program; see the file COPYING. If not, write to-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,-- Boston, MA 02110-1301, USA.{-# LANGUAGE CPP, PatternGuards #-}#include "gadts.h"moduleDarcs.Arguments(DarcsFlag(..),flagToString,applyDefaults,nubOptions,maxCount,isin,arein,setEnvDarcsPatches,setEnvDarcsFiles,fixFilePathOrStd,fixUrl,fixUrlFlag,fixSubPaths,maybeFixSubPaths,DarcsAtomicOption(..),atomicOptions,DarcsOption(..),optionFromDarcsOption,help,listOptions,listFiles,anyVerbosity,disable,restrictPaths,notest,test,workingRepoDir,remoteRepo,leaveTestDir,possiblyRemoteRepoDir,getRepourl,listRegisteredFiles,listUnregisteredFiles,author,getAuthor,getEasyAuthor,getSendmailCmd,fileHelpAuthor,environmentHelpEmail,patchnameOption,distnameOption,logfile,rmlogfile,fromOpt,subject,getSubject,charset,getCharset,inReplyTo,getInReplyTo,target,ccSend,ccApply,getCc,output,outputAutoName,recursive,patchFormatChoices,upgradeFormat,useWorkingDir,askdeps,ignoretimes,lookforadds,askLongComment,keepDate,sendmailCmd,environmentHelpSendmail,sign,verify,editDescription,reponame,creatorhash,applyConflictOptions,reply,pullConflictOptions,useExternalMerge,depsSel,nocompress,uncompressNocompress,repoCombinator,optionsLatex,reorderPatches,noskipBoring,allowProblematicFilenames,applyas,humanReadable,machineReadable,changesReverse,onlyToFiles,changesFormat,matchOneContext,matchOneNontag,matchMaxcount,sendToContext,getContext,pipeInteractive,allInteractive,allPipeInteractive,summary,unified,tokens,partial,diffCmdFlag,diffflags,unidiff,xmloutput,pauseForGui,forceReplace,dryRun,dryRunNoxml,printDryRunMessageAndExit,showFriendly,matchOne,matchSeveral,matchRange,matchSeveralOrRange,happyForwarding,matchSeveralOrLast,setDefault,setScriptsExecutableOption,bisect,sibling,flagsToSiblings,relink,files,directories,pending,posthookCmd,posthookPrompt,getPosthookCmd,prehookCmd,prehookPrompt,getPrehookCmd,nullFlag,umaskOption,storeInMemory,patchSelectFlag,networkOptions,noCache,allowUnrelatedRepos,checkOrRepair,justThisRepo,optimizePristine,optimizeHTTP,getOutput,makeScriptsExecutable,usePacks,recordRollback,amendUnrecord)whereimportSystem.Console.GetOptimportSystem.Directory(doesDirectoryExist)importStorage.Hashed.AnchoredPath(anchorPath)importStorage.Hashed.Plain(readPlainTree)importStorage.Hashed.Tree(list,expand,emptyTree)importData.List((\\),nub,intercalate)importData.Maybe(fromMaybe,listToMaybe,maybeToList,isNothing,catMaybes,mapMaybe)importSystem.Exit(ExitCode(ExitSuccess),exitWith)importControl.Monad(when,unless)importControl.Applicative((<$>))importData.Char(isDigit)#ifndef WIN32importPrinter(renderString)importSystem.Posix.Env(setEnv)importDarcs.Patch(listTouchedFiles)importProgress(beginTedious,endTedious,tediousSize,finishedOneIO)#endifimportDarcs.Patch.PatchInfoAnd(PatchInfoAnd,info,hopefullyM)importDarcs.Patch.Apply(ApplyState)importDarcs.Patch(RepoPatch,Patchy,showNicely,description,xmlSummary)importDarcs.Patch.Info(toXml)importDarcs.Witnesses.Ordered(FL,mapFL)importqualifiedDarcs.Patch(summary)importDarcs.Utils(askUser,askUserListItem,maybeGetEnv,firstJustIO,catchall,withCurrentDirectory)importDarcs.Repository.Prefs(getPreflist,getGlobal,globalPrefsDirDoc)importDarcs.Repository.State(restrictBoring,applyTreeFilter,readRecordedAndPending)importDarcs.Repository(setScriptsExecutablePatches)importDarcs.URL(isFile)importDarcs.RepoPath(AbsolutePath,AbsolutePathOrStd,SubPath,toFilePath,makeSubPathOf,ioAbsolute,ioAbsoluteOrStd,makeAbsolute,makeAbsoluteOrStd)importDarcs.Patch.MatchData(patchMatch)importDarcs.Flags(DarcsFlag(..),maxCount,defaultFlag)importDarcs.Repository(withRepository,RepoJob(..))importDarcs.Global(darcsdir)importDarcs.Lock(writeLocaleFile)importPrinter(Doc,putDocLn,text,vsep,($$),vcat,insertBeforeLastline,prefix)importByteStringUtils(decodeString)importStorage.Hashed.Tree(Tree)#include "impossible.h"dataFlagContent=NoContent|AbsoluteContentAbsolutePath|AbsoluteOrStdContentAbsolutePathOrStd|StringContentStringderiving(Eq,Show,Ord)-- getContent is very tedious to write, but this is the only way (that-- I know of) to guarantee that it works for all flags (which then-- guarantees that isAnAbsolute, isa, flagToString, etc also work-- properly)-- | 'getContentString' returns the content of a flag, if any.-- For instance, the content of @Author \"Louis Aragon\"@ is @StringContent-- \"Louis Aragon\"@, while the content of @Pipe@ is @NoContent@getContent::DarcsFlag->FlagContentgetContent(PatchNames)=StringContentsgetContent(Outputs)=AbsoluteOrStdContentsgetContentVerbose=NoContentgetContentHelp=NoContentgetContentListOptions=NoContentgetContentTest=NoContentgetContentNoTest=NoContentgetContentOnlyChangesToFiles=NoContentgetContentChangesToAllFiles=NoContentgetContentLeaveTestDir=NoContentgetContentNoLeaveTestDir=NoContentgetContentTimings=NoContentgetContentDebug=NoContentgetContentDebugVerbose=NoContentgetContentDebugHTTP=NoContentgetContentNormalVerbosity=NoContentgetContentQuiet=NoContentgetContent(Targets)=StringContentsgetContent(Ccs)=StringContentsgetContent(Subjects)=StringContentsgetContent(Charsets)=StringContentsgetContent(InReplyTos)=StringContentsgetContent(SendmailCmds)=StringContentsgetContent(Authors)=StringContentsgetContent(OnePatchs)=StringContentsgetContent(SeveralPatchs)=StringContentsgetContent(AfterPatchs)=StringContentsgetContent(UpToPatchs)=StringContentsgetContent(TagNames)=StringContentsgetContent(LastNs)=StringContent(shows)getContent(MaxCounts)=StringContent(shows)getContent(OneTags)=StringContentsgetContent(AfterTags)=StringContentsgetContent(UpToTags)=StringContentsgetContent(Contexts)=AbsoluteContentsgetContentGenContext=NoContentgetContent(LogFiles)=AbsoluteContentsgetContent(OutputAutoNames)=AbsoluteContentsgetContentNumberPatches=NoContentgetContent(PatchIndexRange__)=NoContent-- FIXME this doesn't fit into a neat categorygetContentCount=NoContentgetContentAll=NoContentgetContentRecursive=NoContentgetContentNoRecursive=NoContentgetContentReorder=NoContentgetContentRestrictPaths=NoContentgetContentDontRestrictPaths=NoContentgetContentAskDeps=NoContentgetContentNoAskDeps=NoContentgetContentRmLogFile=NoContentgetContentDontRmLogFile=NoContentgetContent(DistNames)=StringContentsgetContent(CreatorHashs)=StringContentsgetContent(SignAss)=StringContentsgetContent(SignSSLs)=StringContentsgetContent(Verifys)=AbsoluteContentsgetContent(VerifySSLs)=AbsoluteContentsgetContentIgnoreTimes=NoContentgetContentDontIgnoreTimes=NoContentgetContentLookForAdds=NoContentgetContentNoLookForAdds=NoContentgetContentAnyOrder=NoContentgetContentIntersection=NoContentgetContentUnified=NoContentgetContentNonUnified=NoContentgetContentUnion=NoContentgetContentComplement=NoContentgetContentSign=NoContentgetContentNoSign=NoContentgetContentHappyForwarding=NoContentgetContentNoHappyForwarding=NoContentgetContent(RemoteDarcsOpts)=StringContentsgetContent(Tokss)=StringContentsgetContent(WorkRepoDirs)=StringContentsgetContent(WorkRepoUrls)=StringContentsgetContent(RemoteRepos)=StringContentsgetContent(NewRepos)=StringContentsgetContent(Replys)=StringContentsgetContentEditDescription=NoContentgetContentNoEditDescription=NoContentgetContentEditLongComment=NoContentgetContentNoEditLongComment=NoContentgetContentPromptLongComment=NoContentgetContentKeepDate=NoContentgetContentNoKeepDate=NoContentgetContentAllowConflicts=NoContentgetContentMarkConflicts=NoContentgetContentNoAllowConflicts=NoContentgetContentSkipConflicts=NoContentgetContentBoring=NoContentgetContentSkipBoring=NoContentgetContentAllowCaseOnly=NoContentgetContentDontAllowCaseOnly=NoContentgetContentAllowWindowsReserved=NoContentgetContentDontAllowWindowsReserved=NoContentgetContentDontGrabDeps=NoContentgetContentDontPromptForDependencies=NoContentgetContentPromptForDependencies=NoContentgetContentCompress=NoContentgetContentNoCompress=NoContentgetContentUnCompress=NoContentgetContentMachineReadable=NoContentgetContentHumanReadable=NoContentgetContentPipe=NoContentgetContentInteractive=NoContentgetContentSummary=NoContentgetContentNoSummary=NoContentgetContent(ApplyAss)=StringContentsgetContent(DiffCmds)=StringContentsgetContent(ExternalMerges)=StringContentsgetContentPauseForGui=NoContentgetContentNoPauseForGui=NoContentgetContent(DiffFlagss)=StringContentsgetContent(OnePattern_)=NoContent-- FIXME!!!getContent(SeveralPattern_)=NoContent-- FIXME!!!getContent(UpToPattern_)=NoContent-- FIXME!!!getContent(AfterPattern_)=NoContent-- FIXME!!!getContentReverse=NoContentgetContentForward=NoContentgetContentComplete=NoContentgetContentLazy=NoContentgetContent(FixFilePath__)=NoContent-- FIXME!!!getContentXMLOutput=NoContentgetContentForceReplace=NoContentgetContentNonApply=NoContentgetContentNonVerify=NoContentgetContentNonForce=NoContentgetContentDryRun=NoContentgetContent(SetDefault_)=NoContentgetContent(NoSetDefault_)=NoContentgetContentDisable=NoContentgetContentSetScriptsExecutable=NoContentgetContentDontSetScriptsExecutable=NoContentgetContentBisect=NoContentgetContentUseHashedInventory=NoContentgetContentUseFormat2=NoContentgetContentNoUpdateWorking=NoContentgetContentUpgradeFormat=NoContentgetContentRelink=NoContentgetContentFiles=NoContentgetContentNoFiles=NoContentgetContentDirectories=NoContentgetContentNoDirectories=NoContentgetContentPending=NoContentgetContentNoPending=NoContentgetContentNoPosthook=NoContentgetContentAskPosthook=NoContentgetContent(Siblings)=AbsoluteContentsgetContent(PosthookCmds)=StringContentsgetContentRunPosthook=NoContentgetContentNoPrehook=NoContentgetContentRunPrehook=NoContentgetContentAskPrehook=NoContentgetContentStoreInMemory=NoContentgetContentApplyOnDisk=NoContentgetContentNoHTTPPipelining=NoContentgetContentPacks=NoContentgetContentNoPacks=NoContentgetContentNoCache=NoContentgetContentNullFlag=NoContentgetContent(PrehookCmds)=StringContentsgetContent(UMasks)=StringContentsgetContentAllowUnrelatedRepos=NoContentgetContentCheck=NoContentgetContentRepair=NoContentgetContentJustThisRepo=NoContentgetContentOptimizePristine=NoContentgetContentOptimizeHTTP=NoContentgetContentRecordRollback=NoContentgetContentNoRecordRollback=NoContentgetContentAmendUnrecord=NoContentgetContentNoAmendUnrecord=NoContentgetContentUseWorkingDir=NoContentgetContentUseNoWorkingDir=NoContentgetContentString::DarcsFlag->MaybeStringgetContentStringf=doStringContents<-Just$getContentfreturns-- | @a `'isa'` b@ tests whether @a@ is flag @b@ with a string argument.-- @b@ typically is a Flag constructor expecting a string-- For example, @(Author \"Ted Hughes\") `isa` Author@ returns true.isa::DarcsFlag->(String->DarcsFlag)->Boola`isa`b=casegetContentStringaofNothing->FalseJusts->a==bs-- | @a `'isAnAbsolute'` b@ tests whether @a@ is flag @b@ with an absolute path argument.-- @b@ typically is a Flag constructor expecting an absolute path argument-- For example, @(Context contextfile) `isAnAbsolute` Context@ returns true.isAnAbsolute::DarcsFlag->(AbsolutePath->DarcsFlag)->BoolisAnAbsolutefx=casegetContentfofAbsoluteContents->f==xs_->False-- | @a `'isAnAbsoluteOrStd'` b@ tests whether @a@ is flag @b@ with a path argument.-- @b@ typically is a Flag constructor expecting a path argument-- For example, @(Output o) `isAnAbsoluteOrStd` @ returns true.isAnAbsoluteOrStd::DarcsFlag->(AbsolutePathOrStd->DarcsFlag)->BoolisAnAbsoluteOrStdfx=casegetContentfofAbsoluteOrStdContents->f==xs_->Falseisin::DarcsAtomicOption->[DarcsFlag]->Bool(DarcsInternalOptionf)`isin`fs=f`elem`fs(DarcsNoArgOption__f_)`isin`fs=f`elem`fs(DarcsArgOption__f__)`isin`fs=any(`isa`f)fs(DarcsAbsPathOption__f__)`isin`fs=any(`isAnAbsolute`f)fs(DarcsAbsPathOrStdOption__f__)`isin`fs=any(`isAnAbsoluteOrStd`f)fs(DarcsOptAbsPathOption___f__)`isin`fs=any(`isAnAbsolute`f)fsarein::DarcsOption->[DarcsFlag]->Boolo`arein`fs=any(`isin`fs)(atomicOptionso)-- | A type for darcs' options. The value contains the command line-- switch(es) for the option, a help string, and a function to build a-- @DarcsFlag@ from the command line arguments. for each constructor,-- 'shortSwitches' represents the list of short command line switches-- which invoke the option, longSwitches the list of long command line-- switches, optDescr the description of the option, and argDescr the description-- of its argument, if any. mkFlag is a function which makes a @DarcsFlag@ from-- the arguments of the option.dataDarcsAtomicOption=DarcsArgOption[Char][String](String->DarcsFlag)StringString-- ^ @DarcsArgOption shortSwitches longSwitches mkFlag ArgDescr OptDescr@-- The constructor for options with a string argument, such as-- @--tag@|DarcsAbsPathOption[Char][String](AbsolutePath->DarcsFlag)StringString-- ^ @DarcsAbsPathOption shortSwitches longSwitches mkFlag ArgDescr OptDescr@-- The constructor for options with an absolute path argument, such as-- @--sibling@|DarcsAbsPathOrStdOption[Char][String](AbsolutePathOrStd->DarcsFlag)StringString-- ^ @DarcsAbsPathOrStdOption shortSwitches longSwitches mkFlag ArgDescr OptDescr@-- The constructor for options with a path argument, such as @-o@|DarcsOptAbsPathOption[Char][String]String(AbsolutePath->DarcsFlag)StringString-- ^ @DarcsOptAbsPathOrStdOption shortSwitches longSwitches defaultPath-- mkFlag ArgDescr OptDescr@ where defaultPath is a default value-- for the Path, as a string to be parsed as if it had been given-- on the command line.-- The constructor for options with an optional path argument, such as @-O@|DarcsNoArgOption[Char][String]DarcsFlagString-- ^ @DarcsNoArgOption shortSwitches longSwitches mkFlag optDescr@-- The constructon fon options with no arguments.|DarcsInternalOptionDarcsFlag-- ^ @DarcsInternalOption@-- An option just for internal use (e.g. defaulting), not directly available to the user.dataDarcsOption=DarcsSingleOptionDarcsAtomicOption|DarcsMultipleChoiceOption[DarcsAtomicOption]-- ^ A constructor for grouping related options together, such as-- @--hashed@ and @--darcs-2@.|DarcsMutuallyExclusive[DarcsAtomicOption]-- choices([DarcsFlag]->[DarcsFlag])-- settertypeNoArgPieces=(DarcsFlag->String->DarcsAtomicOption,DarcsFlag,String)mkMutuallyExclusive::[NoArgPieces]-- ^ before->NoArgPieces-- ^ default->[NoArgPieces]-- ^ after->DarcsOptionmkMutuallyExclusiveos1od_os2=DarcsMutuallyExclusive(mapoption(os1++(od:os2)))(defaultFlag(mapflag(os1++os2))(flagod))whereod=third(++" [DEFAULT]")od_flag(_,f,_)=foption(x,y,z)=xyzthirdf(x,y,z)=(x,y,fz)nubOptions::[DarcsOption]->[DarcsFlag]->[DarcsFlag]nubOptions[]opts=optsnubOptions(DarcsMutuallyExclusivech_:options)opts=nubOptionsoptions$collapseoptswherecollapse(x:xs)|x`elem`flagsch=x:clearxs|otherwise=x:collapsexscollapse[]=[]clear(x:xs)|x`elem`flagsch=clearxs|otherwise=x:clearxsclear[]=[]flags(DarcsNoArgOption__fl_:xs)=fl:flagsxsflags(DarcsInternalOptionfl:xs)=fl:flagsxsflags(_:xs)=flagsxsflags[]=[]nubOptions(_:options)opts=nubOptionsoptionsoptsapplyDefaults::[DarcsOption]->[DarcsFlag]->[DarcsFlag]applyDefaultsopts=foldr(.)id(mapMaybegetSetteropts)wheregetSetter(DarcsMutuallyExclusive_f)=JustfgetSetter_=NothingoptionFromDarcsAtomicOption::AbsolutePath->DarcsAtomicOption->Maybe(OptDescrDarcsFlag)optionFromDarcsAtomicOption_(DarcsInternalOption_)=NothingoptionFromDarcsAtomicOption_(DarcsNoArgOptionabch)=Just$Optionab(NoArgc)hoptionFromDarcsAtomicOption_(DarcsArgOptionabcnh)=Just$Optionab(ReqArgcn)hoptionFromDarcsAtomicOptionwd(DarcsAbsPathOrStdOptionabcnh)=Just$Optionab(ReqArg(c.makeAbsoluteOrStdwd)n)hoptionFromDarcsAtomicOptionwd(DarcsAbsPathOptionabcnh)=Just$Optionab(ReqArg(c.makeAbsolutewd)n)hoptionFromDarcsAtomicOptionwd(DarcsOptAbsPathOptionabdcnh)=Just$Optionab(OptArg(c.makeAbsolutewd.fromMaybed)n)hatomicOptions::DarcsOption->[DarcsAtomicOption]atomicOptions(DarcsSingleOptionx)=[x]atomicOptions(DarcsMultipleChoiceOptionxs)=xsatomicOptions(DarcsMutuallyExclusivexs_)=xsoptionFromDarcsOption::AbsolutePath->DarcsOption->[OptDescrDarcsFlag]optionFromDarcsOptionwd=mapMaybe(optionFromDarcsAtomicOptionwd).atomicOptions-- | 'concat_option' creates a DarcsMultipleChoiceOption from a list of-- option, flattening any DarcsMultipleChoiceOption in the list.concatOptions::[DarcsOption]->DarcsOptionconcatOptions=DarcsMultipleChoiceOption.concatMapatomicOptionsextractFixPath::[DarcsFlag]->Maybe(AbsolutePath,AbsolutePath)extractFixPath[]=NothingextractFixPath((FixFilePathrepoorig):_)=Just(repo,orig)extractFixPath(_:fs)=extractFixPathfsfixFilePath::[DarcsFlag]->FilePath->IOAbsolutePathfixFilePathoptsf=caseextractFixPathoptsofNothing->bug"Can't fix path in fixFilePath"Just(_,o)->withCurrentDirectoryo$ioAbsoluteffixFilePathOrStd::[DarcsFlag]->FilePath->IOAbsolutePathOrStdfixFilePathOrStdoptsf=caseextractFixPathoptsofNothing->bug"Can't fix path in fixFilePathOrStd"Just(_,o)->withCurrentDirectoryo$ioAbsoluteOrStdffixUrlFlag::[DarcsFlag]->DarcsFlag->IODarcsFlagfixUrlFlagopts(RemoteRepof)=RemoteRepo`fmap`fixUrloptsffixUrlFlag_f=returnffixUrl::[DarcsFlag]->String->IOStringfixUrloptsf=ifisFilefthentoFilePath`fmap`fixFilePathoptsfelsereturnf-- | @maybeFixSubPaths files@ tries to turn the file paths in its argument into-- @SubPath@s.---- When converting a relative path to an absolute one, this function first tries-- to interpret the relative path with respect to the current working directory.-- If that fails, it tries to interpret it with respect to the repository-- directory. Only when that fails does it put a @Nothing@ in the result at the-- position of the path that cannot be converted.---- It is intended for validating file arguments to darcs commands.maybeFixSubPaths::[DarcsFlag]->[FilePath]->IO[MaybeSubPath]maybeFixSubPathsflagsfs=withCurrentDirectoryo$dofixedFs<-mapMfixitfsletbads=snd.unzip.filter(isNothing.fst)$zipfixedFsfsunless(nullbads).putStrLn$"Ignoring non-repository paths: "++intercalate", "badsreturnfixedFswhere(r,o)=caseextractFixPathflagsofJustxxx->xxxNothing->bug"Can't fix path in fixSubPaths"fixitp=doap<-ioAbsolutepcasemakeSubPathOfrapofJustsp->return$JustspNothing->withCurrentDirectoryr$doabsolutePathByRepodir<-ioAbsolutepreturn$makeSubPathOfrabsolutePathByRepodir-- | @fixSubPaths files@ returns the @SubPath@s for the paths in @files@ that-- are inside the repository, preserving their order. Paths in @files@ that are-- outside the repository directory are not in the result.---- When converting a relative path to an absolute one, this function first tries-- to interpret the relative path with respect to the current working directory.-- If that fails, it tries to interpret it with respect to the repository-- directory. Only when that fails does it omit the path from the result.---- It is intended for validating file arguments to darcs commands.fixSubPaths::[DarcsFlag]->[FilePath]->IO[SubPath]fixSubPathsflagsfs=nub.catMaybes<$>(maybeFixSubPathsflags$filter(not.null)fs)-- | 'list_option' is an option which lists the command's argumentslistOptions::DarcsOptionlistOptions=DarcsSingleOption$DarcsNoArgOption[]["list-options"]ListOptions"simply list the command's arguments"flagToString::[DarcsOption]->DarcsFlag->MaybeStringflagToStringxf=listToMaybe$mapMaybef2o$concatMapatomicOptionsxwheref2o(DarcsArgOption_(s:_)c__)=doarg<-getContentStringfifcarg==fthenreturn$unwords[('-':'-':s),arg]elseNothingf2o(DarcsNoArgOption_(s:_)f'_)|f==f'=Just('-':'-':s)f2o_=NothingpipeInteractive,allPipeInteractive,allInteractive,humanReadable,diffflags,allowProblematicFilenames,noskipBoring,askLongComment,matchOneNontag,changesReverse,creatorhash,changesFormat,matchOneContext,happyForwarding,sendToContext,diffCmdFlag,storeInMemory,useExternalMerge,pauseForGui,pullConflictOptions,target,ccSend,ccApply,applyConflictOptions,reply,xmloutput,distnameOption,patchnameOption,editDescription,output,outputAutoName,unidiff,repoCombinator,unified,summary,uncompressNocompress,subject,charset,inReplyTo,nocompress,matchSeveralOrRange,matchSeveralOrLast,author,askdeps,lookforadds,ignoretimes,test,notest,help,forceReplace,allowUnrelatedRepos,matchOne,matchRange,matchSeveral,sendmailCmd,logfile,rmlogfile,leaveTestDir,fromOpt,recordRollback::DarcsOptionsign,applyas,verify::DarcsOptionhelp=DarcsSingleOption$DarcsNoArgOption['h']["help"]Help"shows brief description of command and its arguments"disable::DarcsOptiondisable=DarcsSingleOption$DarcsNoArgOption[]["disable"]Disable"disable this command"anyVerbosity::[DarcsOption]anyVerbosity=[DarcsMultipleChoiceOption[DarcsNoArgOption[]["debug"]Debug"give only debug output",DarcsNoArgOption[]["debug-verbose"]DebugVerbose"give debug and verbose output",DarcsNoArgOption[]["debug-http"]DebugHTTP"give debug output for libcurl",DarcsNoArgOption['v']["verbose"]Verbose"give verbose output",DarcsNoArgOption['q']["quiet"]Quiet"suppress informational output",DarcsNoArgOption[]["standard-verbosity"]NormalVerbosity"neither verbose nor quiet output"],DarcsSingleOption(DarcsNoArgOption[]["timings"]Timings"provide debugging timings information")]workingRepoDir::DarcsOptionworkingRepoDir=DarcsSingleOption$DarcsArgOption[]["repodir"]WorkRepoDir"DIRECTORY""specify the repository directory in which to run"possiblyRemoteRepoDir::DarcsOptionpossiblyRemoteRepoDir=DarcsSingleOption$DarcsArgOption[]["repo"]WorkRepoUrl"URL""specify the repository URL"-- | 'getRepourl' takes a list of flags and returns the url of the-- repository specified by @Repodir \"directory\"@ in that list of flags, if any.-- This flag is present if darcs was invoked with @--repodir=DIRECTORY@getRepourl::[DarcsFlag]->MaybeStringgetRepourl[]=NothinggetRepourl(WorkRepoUrld:_)|not(isFiled)=JustdgetRepourl(_:fs)=getRepourlfs-- | 'remoteRepo' is the option used to specify the URL of the remote-- repository to work withremoteRepo::DarcsOptionremoteRepo=DarcsSingleOption$DarcsArgOption[]["remote-repo"]RemoteRepo"URL""specify the remote repository URL to work with"patchnameOption=DarcsSingleOption$DarcsArgOption['m']["name"](PatchName.decodeString)"PATCHNAME""name of patch"sendToContext=DarcsSingleOption$DarcsAbsPathOption[]["context"]Context"FILENAME""send to context stored in FILENAME"matchOneContext=DarcsMultipleChoiceOption[DarcsArgOption[]["to-match"]mp"PATTERN""select changes up to a patch matching PATTERN",DarcsArgOption[]["to-patch"]OnePatch"REGEXP""select changes up to a patch matching REGEXP",__tag,DarcsAbsPathOption[]["context"]Context"FILENAME""version specified by the context in FILENAME"]wheremps=OnePattern(patchMatchs)matchOne=DarcsMultipleChoiceOption[__match,__patch,__tag,__index]-- [NOTE --index removed from matchOneNontag because issue1926]-- The --index option was removed for 2.5 release because it isn't handled-- by amend-record (see issue1926).---- At this moment, amend-record is the only command that uses 'matchOneNontag',-- so there is no other command affected.matchOneNontag=DarcsMultipleChoiceOption[__match,__patch{- , __index -}]matchSeveral=DarcsMultipleChoiceOption[__matches,__patches,__tags]matchRange=concatOptions$[matchTo,matchFrom,DarcsMultipleChoiceOption[__match,__patch,__last,__indexes]]matchSeveralOrRange=concatOptions[matchTo,matchFrom,DarcsMultipleChoiceOption[__last,__indexes,__matches,__patches,__tags]]matchSeveralOrLast=concatOptions[matchFrom,DarcsMultipleChoiceOption[__last,__matches,__patches,__tags]]matchTo,matchFrom::DarcsOptionmatchTo=DarcsMultipleChoiceOption[DarcsArgOption[]["to-match"]uptop"PATTERN""select changes up to a patch matching PATTERN",DarcsArgOption[]["to-patch"]UpToPatch"REGEXP""select changes up to a patch matching REGEXP",DarcsArgOption[]["to-tag"]UpToTag"REGEXP""select changes up to a tag matching REGEXP"]whereuptops=UpToPattern(patchMatchs)matchFrom=DarcsMultipleChoiceOption[DarcsArgOption[]["from-match"]fromp"PATTERN""select changes starting with a patch matching PATTERN",DarcsArgOption[]["from-patch"]AfterPatch"REGEXP""select changes starting with a patch matching REGEXP",DarcsArgOption[]["from-tag"]AfterTag"REGEXP""select changes starting with a tag matching REGEXP"]wherefromps=AfterPattern(patchMatchs)__tag,__tags,__patch,__patches,__match,__matches,__last,__index,__indexes::DarcsAtomicOption__tag=DarcsArgOption['t']["tag"]OneTag"REGEXP""select tag matching REGEXP"__tags=DarcsArgOption['t']["tags"]OneTag"REGEXP""select tags matching REGEXP"__patch=DarcsArgOption['p']["patch"]OnePatch"REGEXP""select a single patch matching REGEXP"__patches=DarcsArgOption['p']["patches"]SeveralPatch"REGEXP""select patches matching REGEXP"__match=DarcsArgOption[]["match"]mp"PATTERN""select a single patch matching PATTERN"wheremps=OnePattern(patchMatchs)__matches=DarcsArgOption[]["matches"]mp"PATTERN""select patches matching PATTERN"wheremps=SeveralPattern(patchMatchs)__last=DarcsArgOption[]["last"]lastn"NUMBER""select the last NUMBER patches"wherelastn=LastN.numberString__index=DarcsArgOption['n']["index"]indexrange"N""select one patch"whereindexranges=ifallisDigitsthenPatchIndexRange(reads)(reads)elsePatchIndexRange00__indexes=DarcsArgOption['n']["index"]indexrange"N-M""select a range of patches"whereindexranges=ifallisokaysthenif'-'`elem`sthenletx1=takeWhile(/='-')sx2=reverse$takeWhile(/='-')$reversesinPatchIndexRange(readx1)(readx2)elsePatchIndexRange(reads)(reads)elsePatchIndexRange00isokayc=isDigitc||c=='-'matchMaxcount::DarcsOptionmatchMaxcount=DarcsSingleOption$DarcsArgOption[]["max-count"]mc"NUMBER""return only NUMBER results"wheremc=MaxCount.numberString-- | 'getContext' takes a list of flags and returns the context-- specified by @Context c@ in that list of flags, if any.-- This flag is present if darcs was invoked with @--context=FILE@getContext::[DarcsFlag]->MaybeAbsolutePathgetContextxs=listToMaybe[c|Contextc<-xs]notest=DarcsMultipleChoiceOption[DarcsNoArgOption[]["no-test"]NoTest"don't run the test script",DarcsNoArgOption[]["test"]Test"run the test script"]test=DarcsMultipleChoiceOption[DarcsNoArgOption[]["test"]Test"run the test script",DarcsNoArgOption[]["no-test"]NoTest"don't run the test script"]leaveTestDir=DarcsMultipleChoiceOption[DarcsNoArgOption[]["leave-test-directory"]LeaveTestDir"don't remove the test directory",DarcsNoArgOption[]["remove-test-directory"]NoLeaveTestDir"remove the test directory"]recordRollback=DarcsMultipleChoiceOption[DarcsNoArgOption[]["record"]RecordRollback"record the rollback patch (default)",DarcsNoArgOption[]["no-record"]NoRecordRollback"don't record the rollback patch (only roll back in working dir)"]amendUnrecord=DarcsMultipleChoiceOption[DarcsNoArgOption[]["add"]NoAmendUnrecord"add the changes to patch (default)",DarcsNoArgOption[]["unrecord"]AmendUnrecord"subtract the changes from patch"]ignoretimes=DarcsMultipleChoiceOption[DarcsNoArgOption[]["ignore-times"]IgnoreTimes"don't trust the file modification times",DarcsNoArgOption[]["no-ignore-times"]DontIgnoreTimes"trust modification times to find modified files [DEFAULT]"]lookforadds=DarcsMultipleChoiceOption[DarcsNoArgOption['l']["look-for-adds"]LookForAdds"look for (non-boring) files that could be added",DarcsNoArgOption[]["dont-look-for-adds","no-look-for-adds"]NoLookForAdds"don't look for any files that could be added [DEFAULT]"]askdeps=DarcsMultipleChoiceOption[DarcsNoArgOption[]["ask-deps"]AskDeps"ask for extra dependencies",DarcsNoArgOption[]["no-ask-deps"]NoAskDeps"don't ask for extra dependencies"]askLongComment=DarcsMultipleChoiceOption[DarcsNoArgOption[]["edit-long-comment"]EditLongComment"edit the long comment by default",DarcsNoArgOption[]["skip-long-comment"]NoEditLongComment"don't give a long comment",DarcsNoArgOption[]["prompt-long-comment"]PromptLongComment"prompt for whether to edit the long comment"]keepDate::DarcsOptionkeepDate=DarcsMultipleChoiceOption[DarcsNoArgOption[]["keep-date"]KeepDate"keep the date of the original patch",DarcsNoArgOption[]["no-keep-date"]NoKeepDate"use the current date for the amended patch"]logfile=DarcsSingleOption$DarcsAbsPathOption[]["logfile"]LogFile"FILE""give patch name and comment in file"rmlogfile=DarcsMultipleChoiceOption[DarcsNoArgOption[]["delete-logfile"]RmLogFile"delete the logfile when done",DarcsNoArgOption[]["no-delete-logfile"]DontRmLogFile"keep the logfile when done [DEFAULT]"]author=DarcsSingleOption$DarcsArgOption['A']["author"](Author.decodeString)"EMAIL""specify author id"fromOpt=DarcsSingleOption$DarcsArgOption[]["from"](Author.decodeString)"EMAIL""specify email address"fileHelpAuthor::[String]fileHelpAuthor=["Each patch is attributed to its author, usually by email address (for","example, `Fred Bloggs <fred@example.net>'). Darcs looks in several","places for this author string: the --author option, the files","_darcs/prefs/author (in the repository) and "++globalPrefsDirDoc++"author (in your","home directory), and the environment variables $DARCS_EMAIL and","$EMAIL. If none of those exist, Darcs will prompt you for an author","string and write it to _darcs/prefs/author. Note that if if you have more","than one email address, note that you can put them all in "++globalPrefsDirDoc++"author,","one author per line. Darcs will still prompt you for an author, but it","allow you to select from the list or type in an alternative."]environmentHelpEmail::([String],[String])environmentHelpEmail=(["DARCS_EMAIL","EMAIL"],fileHelpAuthor)-- | 'getAuthor' takes a list of flags and returns the author of the-- change specified by @Author \"Leo Tolstoy\"@ in that list of flags, if any.-- Otherwise, if @Pipe@ is present, asks the user who is the author and-- returns the answer. If neither are present, try to guess the author,-- from @_darcs/prefs@, and if it's not possible, ask the user.getAuthor::[DarcsFlag]->IOStringgetAuthor(Authora:_)=returnagetAuthor(Pipe:_)=askUser"Who is the author? "getAuthor(_:flags)=getAuthorflagsgetAuthor[]=doeasy_author<-getEasyAuthorcaseeasy_authorof[a]->returna[]->askForAuthorshortPromptlongPromptas->askForAuthor(fancyPromptas)(fancyPromptas)whereshortPrompt=askUser"What is your email address? "longPrompt=askUser"What is your email address (e.g. Fred Bloggs <fred@example.net>)? "fancyPromptxs=doputDocLn$text""$$text"You have saved the following email addresses to your global settings:"str<-askUserListItem"Please select an email address for this repository: "(xs++["Other"])ifstr=="Other"thenlongPromptelsereturnstraskForAuthoraskfn1askfn2=doaminrepo<-doesDirectoryExist(darcsdir++"/prefs")ifaminrepothendoputDocLn$text"Each patch is attributed to its author, usually by email address (for"$$text"example, `Fred Bloggs <fred@example.net>'). Darcs could not determine"$$text"your email address, so you will be prompted for it."$$text""$$text("Your address will be stored in "++darcsdir++"/prefs/author.")$$text"It will be used for all patches recorded in this repository."$$text("If you move that file to "++globalPrefsDirDoc++"author, it will be used for patches")$$text"you record in ALL repositories."add<-askfn1writeLocaleFile(darcsdir++"/prefs/author")$unlines["# "++line|line<-fileHelpAuthor]++"\n"++addreturnaddelseaskfn2-- | 'getEasyAuthor' tries to get the author name first from the repository preferences,-- then from global preferences, then from environment variables. Returns @[]@-- if it could not get it. Note that it may only return multiple possibilities when-- reading from global preferencesgetEasyAuthor::IO[String]getEasyAuthor=fmap(mapdecodeString)$firstNotNullIO[(take1.nonblank)`fmap`getPreflist"author",nonblank`fmap`getGlobal"author",maybeToList`fmap`maybeGetEnv"DARCS_EMAIL",maybeToList`fmap`maybeGetEnv"EMAIL"]wherenonblank=filter(not.null)-- this could perhaps be simplified with Control.Monad-- but note that we do NOT want to concatenate the resultsfirstNotNullIO[]=return[]firstNotNullIO(e:es)=dov<-e`catchall`return[]ifnullvthenfirstNotNullIOeselsereturnvnocompress=DarcsMultipleChoiceOption[__compress,__dontCompress]uncompressNocompress=DarcsMultipleChoiceOption[__compress,__dontCompress,__uncompress]__compress,__dontCompress,__uncompress::DarcsAtomicOption__compress=DarcsNoArgOption[]["compress"]Compress"create compressed patches"__dontCompress=DarcsNoArgOption[]["dont-compress","no-compress"]NoCompress"don't create compressed patches"__uncompress=DarcsNoArgOption[]["uncompress"]UnCompress"uncompress patches"summary=DarcsMultipleChoiceOption[DarcsNoArgOption['s']["summary"]Summary"summarize changes",DarcsNoArgOption[]["no-summary"]NoSummary"don't summarize changes"]unified=DarcsMultipleChoiceOption[DarcsNoArgOption['u']["unified"]Unified"output changes in a darcs-specific format similar to diff -u",DarcsNoArgOption[]["no-unified"]NonUnified"output changes in darcs' usual format"]unidiff=DarcsMultipleChoiceOption[DarcsNoArgOption['u']["unified"]Unified"pass -u option to diff [DEFAULT]",DarcsNoArgOption[]["no-unified"]NonUnified"output patch in diff's dumb format"]diffCmdFlag=DarcsSingleOption$DarcsArgOption[]["diff-command"]DiffCmd"COMMAND""specify diff command (ignores --diff-opts)"pauseForGui=DarcsMultipleChoiceOption[DarcsNoArgOption[]["pause-for-gui"]PauseForGui"pause for an external diff or merge command to finish [DEFAULT]",DarcsNoArgOption[]["no-pause-for-gui"]NoPauseForGui"return immediately after external diff or merge command finishes"]storeInMemory=DarcsMultipleChoiceOption[DarcsNoArgOption[]["store-in-memory"]StoreInMemory"do patch application in memory rather than on disk",DarcsNoArgOption[]["no-store-in-memory"]ApplyOnDisk"do patch application on disk [DEFAULT]"]target=DarcsSingleOption$DarcsArgOption[]["to"]Target"EMAIL""specify destination email"ccSend=DarcsSingleOption$DarcsArgOption[]["cc"]Cc"EMAIL""mail results to additional EMAIL(s)"ccApply=DarcsSingleOption$DarcsArgOption[]["cc"]Cc"EMAIL""mail results to additional EMAIL(s). Requires --reply"-- |'getCc' takes a list of flags and returns the addresses to send a copy of-- the patch bundle to when using @darcs send@.-- looks for a cc address specified by @Cc \"address\"@ in that list of flags.-- Returns the addresses as a comma separated string.getCc::[DarcsFlag]->StringgetCcfs=lt$mapMaybewhatccfswherewhatcc(Cct)=Justtwhatcc_=Nothinglt[t]=tlt[t,""]=tlt(t:ts)=t++" , "++lttslt[]=""subject=DarcsSingleOption$DarcsArgOption[]["subject"]Subject"SUBJECT""specify mail subject"-- |'getSubject' takes a list of flags and returns the subject of the mail-- to be sent by @darcs send@. Looks for a subject specified by-- @Subject \"subject\"@ in that list of flags, if any.-- This flag is present if darcs was invoked with @--subject=SUBJECT@getSubject::[DarcsFlag]->MaybeStringgetSubject(Subjects:_)=JustsgetSubject(_:fs)=getSubjectfsgetSubject[]=Nothingcharset=DarcsSingleOption$DarcsArgOption[]["charset"]Charset"CHARSET""specify mail charset"getCharset::[DarcsFlag]->MaybeStringgetCharset(Charsets:_)=JustsgetCharset(_:fs)=getCharsetfsgetCharset[]=NothinginReplyTo=DarcsSingleOption$DarcsArgOption[]["in-reply-to"]InReplyTo"EMAIL""specify in-reply-to header"getInReplyTo::[DarcsFlag]->MaybeStringgetInReplyTo(InReplyTos:_)=JustsgetInReplyTo(_:fs)=getInReplyTofsgetInReplyTo[]=Nothingoutput=DarcsSingleOption$DarcsAbsPathOrStdOption['o']["output"]Output"FILE""specify output filename"outputAutoName=DarcsSingleOption$DarcsOptAbsPathOption['O']["output-auto-name"]"."OutputAutoName"DIRECTORY""output to automatically named file in DIRECTORY, default: current directory"getOutput::[DarcsFlag]->FilePath->MaybeAbsolutePathOrStdgetOutput(Outputa:_)_=returnagetOutput(OutputAutoNamea:_)f=return$makeAbsoluteOrStdafgetOutput(_:flags)f=getOutputflagsfgetOutput[]_=NothingeditDescription=mkMutuallyExclusive[]yes[no]whereyes=(DarcsNoArgOption[]["edit-description"],EditDescription,"edit the patch bundle description")no=(DarcsNoArgOption[]["dont-edit-description","no-edit-description"],NoEditDescription,"don't edit the patch bundle description")distnameOption=DarcsSingleOption$DarcsArgOption['d']["dist-name"]DistName"DISTNAME""name of version"recursive::String->DarcsOptionrecursiveh=DarcsMultipleChoiceOption[DarcsNoArgOption['r']["recursive"]Recursiveh,DarcsNoArgOption[]["not-recursive","no-recursive"]NoRecursive("don't "++h)]patchFormatChoices::DarcsOptionpatchFormatChoices=DarcsMultipleChoiceOption[DarcsNoArgOption[]["hashed"]UseHashedInventory"Some new features. Compatible with older repos",DarcsNoArgOption[]["darcs-2"]UseFormat2"All features. Related repos must use same format [DEFAULT]."]useWorkingDir::DarcsOptionuseWorkingDir=DarcsMultipleChoiceOption[DarcsNoArgOption[]["with-working-dir"]UseWorkingDir"Create a working directory (normal repository)",DarcsNoArgOption[]["no-working-dir"]UseNoWorkingDir"Do not create a working directory (bare repository)"]upgradeFormat::DarcsOptionupgradeFormat=DarcsSingleOption$DarcsNoArgOption[]["upgrade"]UpgradeFormat"upgrade repository to latest compatible format"xmloutput=DarcsSingleOption$DarcsNoArgOption[]["xml-output"]XMLOutput"generate XML formatted output"creatorhash=DarcsSingleOption$DarcsArgOption[]["creator-hash"]CreatorHash"HASH""specify hash of creator patch (see docs)"sign=DarcsMultipleChoiceOption[DarcsNoArgOption[]["sign"]Sign"sign the patch with your gpg key",DarcsArgOption[]["sign-as"]SignAs"KEYID""sign the patch with a given keyid",DarcsArgOption[]["sign-ssl"]SignSSL"IDFILE""sign the patch using openssl with a given private key",DarcsNoArgOption[]["dont-sign","no-sign"]NoSign"don't sign the patch"]applyas=DarcsMultipleChoiceOption[DarcsArgOption[]["apply-as"]ApplyAs"USERNAME""apply patch as another user using sudo",DarcsNoArgOption[]["no-apply-as"]NonApply"don't use sudo to apply as another user [DEFAULT]"]happyForwarding=DarcsMultipleChoiceOption[DarcsNoArgOption[]["happy-forwarding"]HappyForwarding"forward unsigned messages without extra header",DarcsNoArgOption[]["no-happy-forwarding"]NoHappyForwarding"don't forward unsigned messages without extra header [DEFAULT]"]setDefault::Bool->DarcsOptionsetDefaultwantYes|wantYes=mkMutuallyExclusive[yes,no]defaultyes[]|otherwise=mkMutuallyExclusive[yes,no]defaultno[]whereyes=(DarcsNoArgOption[]["set-default"],SetDefaultTrue,"set default repository"++defaultTextwantYes)no=(DarcsNoArgOption[]["no-set-default"],NoSetDefaultTrue,"don't set default repository"++defaultText(notwantYes))defaultyes=(\f_->DarcsInternalOptionf,SetDefaultFalse,"")defaultno=(\f_->DarcsInternalOptionf,NoSetDefaultFalse,"")defaultTextTrue=" [DEFAULT]"defaultTextFalse=""verify=DarcsMultipleChoiceOption[DarcsAbsPathOption[]["verify"]Verify"PUBRING""verify that the patch was signed by a key in PUBRING",DarcsAbsPathOption[]["verify-ssl"]VerifySSL"KEYS""verify using openSSL with authorized keys from file KEYS",DarcsNoArgOption[]["no-verify"]NonVerify"don't verify patch signature"]reponame::DarcsOptionreponame=DarcsSingleOption$DarcsArgOption[]["repo-name","repodir"]NewRepo"DIRECTORY""path of output directory"--repodir is there for compatibility--should be removed eventuallydepsSel::DarcsOptiondepsSel=DarcsMultipleChoiceOption[DarcsNoArgOption[]["no-deps"]DontGrabDeps"don't automatically fulfill dependencies",DarcsNoArgOption[]["dont-prompt-for-dependencies"]DontPromptForDependencies"don't ask about patches that are depended on by matched patches (with --match or --patch)",DarcsNoArgOption[]["prompt-for-dependencies"]PromptForDependencies"prompt about patches that are depended on by matched patches [DEFAULT]"]tokens::DarcsOptiontokens=DarcsSingleOption$DarcsArgOption[]["token-chars"]Toks"\"[CHARS]\"""define token to contain these characters"partial::DarcsOptionpartial=DarcsMultipleChoiceOption[__lazy,__complete]__lazy,__complete::DarcsAtomicOption__lazy=DarcsNoArgOption[]["lazy"]Lazy"get patch files only as needed"__complete=DarcsNoArgOption[]["complete"]Complete"get a complete copy of the repository"forceReplace=DarcsMultipleChoiceOption[DarcsNoArgOption['f']["force"]ForceReplace"proceed with replace even if 'new' token already exists",DarcsNoArgOption[]["no-force"]NonForce"don't force the replace if it looks scary"]reply=DarcsSingleOption$DarcsArgOption[]["reply"]Reply"FROM""reply to email-based patch using FROM address"applyConflictOptions=DarcsMultipleChoiceOption[DarcsNoArgOption[]["mark-conflicts"]MarkConflicts"mark conflicts",DarcsNoArgOption[]["allow-conflicts"]AllowConflicts"allow conflicts, but don't mark them",DarcsNoArgOption[]["no-resolve-conflicts"]NoAllowConflicts"equivalent to --dont-allow-conflicts, for backwards compatibility",DarcsNoArgOption[]["dont-allow-conflicts","no-allow-conflicts"]NoAllowConflicts"fail if there are patches that would create conflicts [DEFAULT]",DarcsNoArgOption[]["skip-conflicts"]SkipConflicts"filter out any patches that would create conflicts"]pullConflictOptions=DarcsMultipleChoiceOption[DarcsNoArgOption[]["mark-conflicts"]MarkConflicts"mark conflicts [DEFAULT]",DarcsNoArgOption[]["allow-conflicts"]AllowConflicts"allow conflicts, but don't mark them",DarcsNoArgOption[]["dont-allow-conflicts","no-allow-conflicts"]NoAllowConflicts"fail if there are patches that would create conflicts",DarcsNoArgOption[]["skip-conflicts"]SkipConflicts"filter out any patches that would create conflicts"]useExternalMerge=DarcsSingleOption$DarcsArgOption[]["external-merge"]ExternalMerge"COMMAND""use external tool to merge conflicts"-- NOTE: I'd rather work to have no uses of dryRunNoxml, so that any time-- --dry-run is a possibility, automated users can examine the results more-- easily with --xml.dryRunNoxml::DarcsOptiondryRunNoxml=DarcsSingleOption$DarcsNoArgOption[]["dry-run"]DryRun"don't actually take the action"dryRun::[DarcsOption]dryRun=[dryRunNoxml,xmloutput]-- | @'showFriendly' flags patch@ returns a 'Doc' representing the right-- way to show @patch@ given the list @flags@ of flags darcs was invoked with.showFriendly::Patchyp=>[DarcsFlag]->pC(xy)->DocshowFriendlyoptsp|Verbose`elem`opts=showNicelyp|Summary`elem`opts=Darcs.Patch.summaryp|otherwise=descriptionp-- | @'printDryRunMessageAndExit' action opts patches@ prints a string-- representing the action that would be taken if the @--dry-run@ option-- had not been passed to darcs. Then darcs exits successfully.-- @action@ is the name of the action being taken, like @\"push\"@-- @opts@ is the list of flags which were sent to darcs-- @patches@ is the sequence of patches which would be touched by @action@.printDryRunMessageAndExit::(RepoPatchp,ApplyStatep~Tree)=>String->[DarcsFlag]->FL(PatchInfoAndp)C(xy)->IO()printDryRunMessageAndExitactionoptspatches=dowhen(DryRun`elem`opts)$doputInfo$text$"Would "++action++" the following changes:"putDocLn$put_modeputInfo$text$""putInfo$text$"Making no changes: this is a dry run."exitWithExitSuccesswhen(All`elem`opts&&Summary`elem`opts)$doputInfo$text$"Will "++action++" the following changes:"putDocLn$put_modewhereput_mode=ifXMLOutput`elem`optsthen(text"<patches>"$$vcat(mapFL(indent.xml_info)patches)$$text"</patches>")else(vsep$mapFL(showFriendlyopts)patches)putInfo=ifXMLOutput`elem`optsthen\_->return()elseputDocLnxml_infopl|Summary`elem`opts=xml_with_summarypl|otherwise=(toXml.info)plxml_with_summaryhp|Justp<-hopefullyMhp=insertBeforeLastline(toXml$infohp)(indent$xmlSummaryp)xml_with_summaryhp=toXml(infohp)indent=prefix" "noskipBoring=DarcsMultipleChoiceOption[DarcsNoArgOption[]["boring"]Boring"don't skip boring files",DarcsNoArgOption[]["no-boring"]SkipBoring"skip boring files [DEFAULT]"]allowProblematicFilenames=DarcsMultipleChoiceOption[DarcsNoArgOption[]["case-ok"]AllowCaseOnly"don't refuse to add files differing only in case",DarcsNoArgOption[]["no-case-ok"]DontAllowCaseOnly"refuse to add files whose name differ only in case [DEFAULT]",DarcsNoArgOption[]["reserved-ok"]AllowWindowsReserved"don't refuse to add files with Windows-reserved names",DarcsNoArgOption[]["no-reserved-ok"]DontAllowWindowsReserved"refuse to add files with Windows-reserved names [DEFAULT]"]diffflags=DarcsSingleOption$DarcsArgOption[]["diff-opts"]DiffFlags"OPTIONS""options to pass to diff"changesFormat=concatOptions$[DarcsMultipleChoiceOption[DarcsNoArgOption[]["context"]GenContext"give output suitable for get --context"],xmloutput,humanReadable,DarcsMultipleChoiceOption[DarcsNoArgOption[]["number"]NumberPatches"number the changes",DarcsNoArgOption[]["count"]Count"output count of changes"]]changesReverse=DarcsMultipleChoiceOption[DarcsNoArgOption[]["reverse"]Reverse"show changes in reverse order",DarcsNoArgOption[]["no-reverse"]Forward"show changes in the usual order [DEFAULT]"]onlyToFiles::DarcsOptiononlyToFiles=DarcsMultipleChoiceOption[DarcsNoArgOption[]["only-to-files"]OnlyChangesToFiles"show only changes to specified files",DarcsNoArgOption[]["no-only-to-files"]ChangesToAllFiles"show changes to all files [DEFAULT]"]humanReadable=DarcsSingleOption$DarcsNoArgOption[]["human-readable"]HumanReadable"give human-readable output"machineReadable=DarcsSingleOption$DarcsNoArgOption[]["machine-readable"]MachineReadable"give machine-readable output"pipe::DarcsAtomicOptionpipe=DarcsNoArgOption[]["pipe"]Pipe"ask user interactively for the patch metadata"interactive::DarcsAtomicOptioninteractive=DarcsNoArgOption['i']["interactive"]Interactive"prompt user interactively"allPatches::DarcsAtomicOptionallPatches=DarcsNoArgOption['a']["all"]All"answer yes to all patches"allInteractive=DarcsMultipleChoiceOption[allPatches,interactive]allPipeInteractive=DarcsMultipleChoiceOption[allPatches,pipe,interactive]pipeInteractive=DarcsMultipleChoiceOption[pipe,interactive]repoCombinator=DarcsMultipleChoiceOption[DarcsNoArgOption[]["intersection"]Intersection"take intersection of all repositories",DarcsNoArgOption[]["union"]Union"take union of all repositories [DEFAULT]",DarcsNoArgOption[]["complement"]Complement"take complement of repositories (in order listed)"]-- | Get a list of all non-boring files and directories in the working copy.listFiles::IO[String]listFiles=dononboring<-restrictBoringemptyTreeworking<-expand=<<applyTreeFilternonboring<$>readPlainTree"."return$map(anchorPath"".fst)$listworking-- | 'listUnregisteredFiles' returns the list of all non-boring unregistered-- files in the repository.listUnregisteredFiles::IO[String]listUnregisteredFiles=dounregd<-listFilesregd<-listRegisteredFilesreturn$unregd\\regd-- (inefficient)-- | 'listRegisteredFiles' returns the list of all registered files in the repository.listRegisteredFiles::IO[String]listRegisteredFiles=dorecorded<-expand=<<withRepository[](RepoJobreadRecordedAndPending)return$map(anchorPath"".fst)$listrecordedoptionsLatex::[DarcsOption]->StringoptionsLatexopts="\\begin{tabular}{lll}\n"++unlines(mapoptionListLatexopts)++"\\end{tabular}\n"latexHelp::String->StringlatexHelph="\\begin{minipage}{7cm}\n\\raggedright\n"++h++"\\end{minipage}\n"optionListLatex::DarcsOption->StringoptionListLatex(DarcsSingleOptiono)=optionLatexooptionListLatex(DarcsMultipleChoiceOptionos)=unlines(mapoptionLatexos)optionListLatex(DarcsMutuallyExclusiveos_)=unlines(mapoptionLatexos)optionLatex::DarcsAtomicOption->StringoptionLatex(DarcsInternalOption_)=""optionLatex(DarcsNoArgOptionab_h)=showShortOptionsa++showLongOptionsb++latexHelph++"\\\\"optionLatex(DarcsArgOptionab_argh)=showShortOptionsa++showLongOptions(map(++(" "++arg))b)++latexHelph++"\\\\"optionLatex(DarcsAbsPathOrStdOptionab_argh)=showShortOptionsa++showLongOptions(map(++(" "++arg))b)++latexHelph++"\\\\"optionLatex(DarcsAbsPathOptionab_argh)=showShortOptionsa++showLongOptions(map(++(" "++arg))b)++latexHelph++"\\\\"optionLatex(DarcsOptAbsPathOptionab__argh)=showShortOptionsa++showLongOptions(map(++("[="++arg++"]"))b)++latexHelph++"\\\\"showShortOptions::[Char]->StringshowShortOptions[]="&"showShortOptions[c]="\\verb!-"++[c]++"! &"showShortOptions(c:cs)="\\verb!-"++[c]++"!,"++showShortOptionscsshowLongOptions::[String]->StringshowLongOptions[]=" &"showLongOptions[s]="\\verb!--"++s++"! &"showLongOptions(s:ss)="\\verb!--"++s++"!,"++showLongOptionssssetScriptsExecutableOption::DarcsOptionsetScriptsExecutableOption=DarcsMultipleChoiceOption[DarcsNoArgOption[]["set-scripts-executable"]SetScriptsExecutable"make scripts executable",DarcsNoArgOption[]["dont-set-scripts-executable","no-set-scripts-executable"]DontSetScriptsExecutable"don't make scripts executable"]bisect::DarcsOptionbisect=DarcsSingleOption$DarcsNoArgOption[]["bisect"]Bisect"binary instead of linear search"relink,sibling::DarcsOptionrelink=DarcsSingleOption$DarcsNoArgOption[]["relink"]Relink"relink random internal data to a sibling"sibling=DarcsSingleOption$DarcsAbsPathOption[]["sibling"]Sibling"URL""specify a sibling directory"-- | 'flagsToSiblings' collects the contents of all @Sibling@ flags in a list of flags.flagsToSiblings::[DarcsFlag]->[AbsolutePath]flagsToSiblings((Siblings):l)=s:(flagsToSiblingsl)flagsToSiblings(_:l)=flagsToSiblingslflagsToSiblings[]=[]reorderPatches::DarcsOptionreorderPatches=DarcsSingleOption$DarcsNoArgOption[]["reorder-patches"]Reorder"reorder the patches in the repository"sendmailCmd=DarcsSingleOption$DarcsArgOption[]["sendmail-command"]SendmailCmd"COMMAND""specify sendmail command"environmentHelpSendmail::([String],[String])environmentHelpSendmail=(["SENDMAIL"],["On Unix, the `darcs send' command relies on sendmail(8). The","`--sendmail-command' or $SENDMAIL environment variable can be used to","provide an explicit path to this program; otherwise the standard","locations /usr/sbin/sendmail and /usr/lib/sendmail will be tried."])-- FIXME: mention the following also:-- * sendmail(8) is not sendmail-specific;-- * nowadays, desktops often have no MTA or an unconfigured MTA ---- which is awful, because it accepts mail but doesn't relay it;-- * in this case, can be a sendmail(8)-emulating wrapper on top of an-- MUA that sends mail directly to a smarthost; and-- * on a multi-user system without an MTA and on which you haven't-- got root, can be msmtp.-- |'getSendmailCmd' takes a list of flags and returns the sendmail command-- to be used by @darcs send@. Looks for a command specified by-- @SendmailCmd \"command\"@ in that list of flags, if any.-- This flag is present if darcs was invoked with @--sendmail-command=COMMAND@-- Alternatively the user can set @$S@@ENDMAIL@ which will be used as a fallback if present.getSendmailCmd::[DarcsFlag]->IOStringgetSendmailCmd(SendmailCmda:_)=returnagetSendmailCmd(_:flags)=getSendmailCmdflagsgetSendmailCmd[]=doeasy_sendmail<-firstJustIO[maybeGetEnv"SENDMAIL"]caseeasy_sendmailofJusta->returnaNothing->return""files::DarcsOptionfiles=DarcsMultipleChoiceOption[DarcsNoArgOption[]["files"]Files"include files in output [DEFAULT]",DarcsNoArgOption[]["no-files"]NoFiles"don't include files in output"]directories::DarcsOptiondirectories=DarcsMultipleChoiceOption[DarcsNoArgOption[]["directories"]Directories"include directories in output [DEFAULT]",DarcsNoArgOption[]["no-directories"]NoDirectories"don't include directories in output"]pending::DarcsOptionpending=DarcsMultipleChoiceOption[DarcsNoArgOption[]["pending"]Pending"reflect pending patches in output [DEFAULT]",DarcsNoArgOption[]["no-pending"]NoPending"only included recorded patches in output"]nullFlag::DarcsOption-- "null" is already takennullFlag=DarcsSingleOption$DarcsNoArgOption['0']["null"]NullFlag"separate file names by NUL characters"-- | Set the DARCS_PATCHES and DARCS_PATCHES_XML environment variables-- with info about the given patches, for use in post-hooks.setEnvDarcsPatches::(RepoPatchp,ApplyStatep~Tree)=>FL(PatchInfoAndp)C(xy)->IO()#ifndef WIN32setEnvDarcsPatchesps=doletk="Defining set of chosen patches"beginTediousktediousSizek3finishedOneIOk"DARCS_PATCHES"setEnvCautiously"DARCS_PATCHES"(renderString$Darcs.Patch.summaryps)finishedOneIOk"DARCS_PATCHES_XML"setEnvCautiously"DARCS_PATCHES_XML"(renderString$text"<patches>"$$vcat(mapFL(toXml.info)ps)$$text"</patches>")finishedOneIOk"DARCS_FILES"setEnvCautiously"DARCS_FILES"(unlines$listTouchedFilesps)endTediousk-- | Set some environment variable to the given value, unless said value-- is longer than 10K characters, in which case do nothing.setEnvCautiously::String->String->IO()setEnvCautiouslyev|toobig(10*1024)v=return()|otherwise=setEnvevTruewheretoobig::Int->[a]->Booltoobig0_=Truetoobig_[]=Falsetoobign(_:xs)=toobig(n-1)xs#elsesetEnvDarcsPatches_=return()#endif-- | Set the DARCS_FILES environment variable to the files touched by the-- given patch, one per line, for use in post-hooks.setEnvDarcsFiles::Patchyp=>pC(xy)->IO()#ifndef WIN32setEnvDarcsFilesps=setEnvCautiously"DARCS_FILES"(unlines$listTouchedFilesps)#elsesetEnvDarcsFiles_=return()#endifposthookCmd::DarcsOptionposthookCmd=DarcsMultipleChoiceOption[DarcsArgOption[]["posthook"]PosthookCmd"COMMAND""specify command to run after this darcs command",DarcsNoArgOption[]["no-posthook"]NoPosthook"don't run posthook command"]posthookPrompt::DarcsOptionposthookPrompt=DarcsMultipleChoiceOption[DarcsNoArgOption[]["prompt-posthook"]AskPosthook"prompt before running posthook [DEFAULT]",DarcsNoArgOption[]["run-posthook"]RunPosthook"run posthook command without prompting"]-- | 'getPosthookCmd' takes a list of flags and returns the posthook command-- specified by @PosthookCmd a@ in that list of flags, if any.getPosthookCmd::[DarcsFlag]->MaybeStringgetPosthookCmd(PosthookCmda:_)=JustagetPosthookCmd(NoPosthook:_)=NothinggetPosthookCmd(_:flags)=getPosthookCmdflagsgetPosthookCmd[]=NothingprehookCmd::DarcsOptionprehookCmd=DarcsMultipleChoiceOption[DarcsArgOption[]["prehook"]PrehookCmd"COMMAND""specify command to run before this darcs command",DarcsNoArgOption[]["no-prehook"]NoPrehook"don't run prehook command"]prehookPrompt::DarcsOptionprehookPrompt=DarcsMultipleChoiceOption[DarcsNoArgOption[]["prompt-prehook"]AskPrehook"prompt before running prehook [DEFAULT]",DarcsNoArgOption[]["run-prehook"]RunPrehook"run prehook command without prompting"]-- | 'getPrehookCmd' takes a list of flags and returns the prehook command-- specified by @PrehookCmd a@ in that list of flags, if any.getPrehookCmd::[DarcsFlag]->MaybeStringgetPrehookCmd(PrehookCmda:_)=JustagetPrehookCmd(NoPrehook:_)=NothinggetPrehookCmd(_:flags)=getPrehookCmdflagsgetPrehookCmd[]=NothingnetworkOptions::[DarcsOption]networkOptions=[DarcsMultipleChoiceOption[DarcsNoArgOption[]["no-http-pipelining"]NoHTTPPipelining"disable HTTP pipelining"],remoteDarcs]remoteDarcs::DarcsOptionremoteDarcs=DarcsSingleOption$DarcsArgOption[]["remote-darcs"]RemoteDarcsOpt"COMMAND""name of the darcs executable on the remote server"noCache::DarcsOptionnoCache=DarcsSingleOption$DarcsNoArgOption[]["no-cache"]NoCache"don't use patch caches"optimizePristine::DarcsOptionoptimizePristine=DarcsSingleOption$DarcsNoArgOption[]["pristine"]OptimizePristine"optimize hashed pristine layout"optimizeHTTP::DarcsOptionoptimizeHTTP=DarcsSingleOption$DarcsNoArgOption[]["http"]OptimizeHTTP"optimize repository for getting over network"usePacks::DarcsOptionusePacks=DarcsMultipleChoiceOption[DarcsNoArgOption[]["packs"]Packs"use repository packs [DEFAULT]",DarcsNoArgOption[]["no-packs"]NoPacks"don't use repository packs"]umaskOption::DarcsOptionumaskOption=DarcsSingleOption$DarcsArgOption[]["umask"]UMask"UMASK""specify umask to use when writing"restrictPaths::DarcsOptionrestrictPaths=DarcsMultipleChoiceOption[DarcsNoArgOption[]["restrict-paths"]RestrictPaths"don't allow darcs to touch external files or repo metadata",DarcsNoArgOption[]["dont-restrict-paths","no-restrict-paths"]DontRestrictPaths"allow darcs to modify any file or directory (unsafe)"]allowUnrelatedRepos=DarcsSingleOption$DarcsNoArgOption[]["ignore-unrelated-repos"]AllowUnrelatedRepos"do not check if repositories are unrelated"justThisRepo::DarcsOptionjustThisRepo=DarcsSingleOption$DarcsNoArgOption[]["just-this-repo"]JustThisRepo"Limit the check or repair to the current repo"check,repair,checkOrRepair::DarcsOptioncheck=DarcsSingleOption$DarcsNoArgOption[]["check"]Check"Specify checking mode"repair=DarcsSingleOption$DarcsNoArgOption[]["repair"]Repair"Specify repair mode"checkOrRepair=concatOptions[check,repair]-- | @'patchSelectFlag' f@ holds whenever @f@ is a way of selecting-- patches such as @PatchName n@.patchSelectFlag::DarcsFlag->BoolpatchSelectFlagAll=TruepatchSelectFlag(PatchName_)=TruepatchSelectFlag(OnePatch_)=TruepatchSelectFlag(SeveralPatch_)=TruepatchSelectFlag(AfterPatch_)=TruepatchSelectFlag(UpToPatch_)=TruepatchSelectFlag(TagName_)=TruepatchSelectFlag(LastN_)=TruepatchSelectFlag(OneTag_)=TruepatchSelectFlag(AfterTag_)=TruepatchSelectFlag(UpToTag_)=TruepatchSelectFlag(OnePattern_)=TruepatchSelectFlag(SeveralPattern_)=TruepatchSelectFlag(AfterPattern_)=TruepatchSelectFlag(UpToPattern_)=TruepatchSelectFlag_=False-- | The integer corresponding to a string, if it's only composed of digits.-- Otherwise, -1.numberString::String->IntnumberString""=-1numberStrings=ifallisDigitsthenreadselse(-1)makeScriptsExecutable::Patchyp=>[DarcsFlag]->pC(xy)->IO()makeScriptsExecutableoptsp=when(SetScriptsExecutable`elem`opts)$setScriptsExecutablePatchesp