diff -r 0294d9beb4c0 -r d4e5428a3b58 CVSSourceCodeManager.st --- a/CVSSourceCodeManager.st Mon Feb 04 13:22:47 2008 +0100 +++ b/CVSSourceCodeManager.st Mon Feb 04 18:08:53 2008 +0100 @@ -4033,6 +4033,7 @@ revisions are ordered newest first (i.e. the last entry is for the initial revision; the first for the most recent one) + Attention: if state = 'dead' that revision is no longer valid. " |tempDir fullName modulePath inStream inHeaderInfo atEnd line idx @@ -4219,6 +4220,200 @@ module:moduleDir ! +revisionLogOfPackageInDirectory:packageDir module:moduleDir + " + The returned information is a list of structures (IdentityDictionary) + each filled with: + #container -> the RCS/CVS container file name + #cvsRoot -> the CVS root (repository) + #filename -> the actual source file name + #newestRevision -> the revisionString of the newest revision + #numberOfRevisions -> the number of revisions in the container (nil for all) + #revisions -> collection of per-revision info (see below) + + firstRev / lastRef specify from which revisions a logEntry is wanted: + -If firstRev is nil, the first revision is the initial revision + otherwise, the log starts with that revision. + -If lastRef is nil, the last revision is the newest revision + otherwise, the log ends with that revision. + + -If both are nil, all logEntries are extracted. + -If both are 0 (not nil), no logEntries are extracted (i.e. only the header). + + per revision info consists of one record per revision: + + #revision -> the revision string + #author -> who checked that revision into the repository + #date -> when was it checked in + #state -> the RCS state + #numberOfChangedLines -> the number of changed line w.r.t the previous + #logMessage -> the checkIn log message + + revisions are ordered newest first + (i.e. the last entry is for the initial revision; the first for the most recent one) + Attention: if state = 'dead' that revision is no longer valid. + " + + |tempDir modulePath inStream inHeaderInfo atEnd line idx + info record revisionRecords s headerOnly msg infoCollection + fn container| + + self use_rlog ifFalse:[ + tempDir := self createTempDirectory:nil forModule:nil. + ]. + + [ + |cmd revArg| + + modulePath := moduleDir , '/' , packageDir. + + self use_rlog ifFalse:[ +self halt. +^ self. +"/ self createEntryFor:fullName +"/ module:moduleDir +"/ in:(tempDir construct:modulePath) +"/ revision:'1.1' +"/ date:'dummy' +"/ special:'' +"/ overwrite:false. + ]. + + revArg := ''. + headerOnly := false. + + headerOnly ifTrue:[ + msg := 'fetching revision info ' + ] ifFalse:[ + msg := 'reading revision log ' + ]. + msg := msg , 'in package ' , modulePath. + self activityNotification:msg,'...'. + + self use_rlog ifTrue:[ + cmd := ('rlog ' , revArg , ' ' , modulePath). + ] ifFalse:[ + cmd := ('log ' , revArg , ' ' , modulePath). + ]. + + inStream := self + executeCVSCommand:cmd + module:moduleDir + inDirectory:tempDir + log:true + pipe:true. + + inStream isNil ifTrue:[ + ('CVSSourceCodeManager [error]: cannot open pipe to cvs log ', modulePath) errorPrintCR. + ^ nil + ]. + + infoCollection := Dictionary new. + [inStream atEnd not] whileTrue:[ + "/ + "/ read the commands pipe output and extract the container info + "/ + info := IdentityDictionary new. + inHeaderInfo := true. + [inHeaderInfo and:[inStream atEnd not]] whileTrue:[ + line:= inStream nextLine. + line notEmptyOrNil ifTrue:[ + |gotIt| + + gotIt := false. + #('RCS file:' #container + 'Working file:' #filename + 'head:' #newestRevision + 'total revisions:' #numberOfRevisions + ) pairWiseDo:[:word :key | + gotIt ifFalse:[ + s := line restAfter:word withoutSeparators:true. + s notNil ifTrue:[info at:key put:s. gotIt := true]. + ] + ]. + gotIt ifFalse:[ + (line startsWith:'symbolic names:') ifTrue:[ + |tags tokens| + + tags := Dictionary new. + line:= inStream nextLine. + [line notNil + and:[(line startsWith:Character space) or:[line startsWith:Character tab]]] whileTrue:[ + tokens := line asCollectionOfSubstringsSeparatedBy:$:. + tags at:(tokens first withoutSeparators) put:(tokens second withoutSeparators). + line:= inStream nextLine. + ]. + info at:#symbolicNames put:tags. + ]. + (line startsWith:'description:') ifTrue:[inHeaderInfo := false]. + ] + ] + ]. + inStream nextLine. "/ skip separating line after description. + + info isEmpty ifTrue:[ + ('CVSSourceCodeManager [warning]: no log for ', modulePath) errorPrintCR. + ] ifFalse:[ + + "/ strip selected revisions from the total-revisions entry + s := info at:#numberOfRevisions. + (idx := s indexOf:$;) ~~ 0 ifTrue:[ + info at:#numberOfRevisions put:(Integer readFrom:(s copyTo:idx - 1)) + ] ifFalse:[ + info at:#numberOfRevisions put:(Integer readFrom:s onError:[1]) + ]. + headerOnly ifFalse:[ + |numRevisions| + + "/ + "/ continue to read the commands pipe output + "/ and extract revision info records + "/ + numRevisions := info at:#numberOfRevisions. + revisionRecords := OrderedCollection new:numRevisions. + info at:#revisions put:revisionRecords. + + atEnd := false. + [atEnd or:[inStream atEnd]] whileFalse:[ + record := self readRevisionLogEntryFromStream:inStream. + record isNil ifTrue:[ + atEnd := true. + ] ifFalse:[ + revisionRecords add:record. + ]. + (numRevisions notNil and:[revisionRecords size >= numRevisions]) ifTrue:[ + atEnd := true + ] + ]. + ]. + ]. + fn := info at:#filename ifAbsent:nil. + fn isNil ifTrue:[ + container := info at:#container ifAbsent:nil. + fn := container asFilename baseName copyWithoutLast:2. "/ remove ',v' suffix + info at:#filename put:fn. + ]. + infoCollection at:(info at:#filename) put:info. + ]. + ] ensure:[ + inStream notNil ifTrue:[inStream close]. + + tempDir notNil ifTrue:[ + OperatingSystem accessDeniedErrorSignal handle:[:ex | + ('CVSSourceCodeManager [warning]: could not remove tempDir ', tempDir pathName) infoPrintCR. + ] do:[ + tempDir recursiveRemove + ]. + ]. + self activityNotification:nil. + ]. + ^ infoCollection + + " + CVSSourceCodeManager revisionLogOfPackageInDirectory:'libbasic3' module:'stx' + " +! + setSymbolicName:symbolicName revision:rev overWrite:overWriteBool class:aClass "set a symbolicName for revision rev. If rev is nil, set it for the head (most recent) revision. @@ -4512,7 +4707,7 @@ !CVSSourceCodeManager class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic3/CVSSourceCodeManager.st,v 1.349 2007-03-28 16:44:09 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic3/CVSSourceCodeManager.st,v 1.350 2008-02-04 17:08:53 cg Exp $' ! ! CVSSourceCodeManager initialize!