More SourceCodeManager API.
Added #streamForClass:fileName:revision:directory:module:cache:
--- a/mercurial/HGChangesetFile.st Tue Dec 04 01:36:59 2012 +0000
+++ b/mercurial/HGChangesetFile.st Tue Dec 04 10:14:28 2012 +0000
@@ -189,6 +189,21 @@
"Created: / 16-11-2012 / 23:41:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!HGChangesetFile methodsFor:'operations'!
+
+copyTo: aStringOrFilename
+ "Writes contents of the receiver to given file"
+
+ HGCommand cat
+ workingDirectory: self repository pathName;
+ path: self pathName;
+ revision: changeset id revno;
+ destination: aStringOrFilename;
+ execute.
+
+ "Created: / 04-12-2012 / 01:58:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!HGChangesetFile methodsFor:'printing & storing'!
printOn:aStream
--- a/mercurial/HGCommand.st Tue Dec 04 01:36:59 2012 +0000
+++ b/mercurial/HGCommand.st Tue Dec 04 10:14:28 2012 +0000
@@ -22,7 +22,7 @@
!
HGCommand subclass:#cat
- instanceVariableNames:'path revision'
+ instanceVariableNames:'path revision destination'
classVariableNames:''
poolDictionaries:''
privateIn:HGCommand
@@ -602,6 +602,14 @@
!HGCommand::cat methodsFor:'accessing'!
+destination
+ ^ destination
+!
+
+destination:aStringOrFilename
+ destination := aStringOrFilename.
+!
+
path
^ path
!
@@ -627,7 +635,7 @@
"
- | pipe output pid environment sema args |
+ | pipe output pid environment sema args sout exec |
pipe := NonPositionableExternalStream makePipe.
output := pipe first.
@@ -648,22 +656,43 @@
]
].
+ sout := destination notNil
+ ifTrue:[destination asFilename writeStream]
+ ifFalse:[pipe second].
sema := Semaphore new name: 'Waiting for hg command to finish'.
- pid := OperatingSystem exec:(self executable) withArguments:args
- environment:environment
- fileDescriptors:{0 . pipe second fileDescriptor . pipe second fileDescriptor}
- fork:true
- newPgrp:false
- inDirectory:self workingDirectory.
+ exec := [
+ pid := OperatingSystem exec:(self executable) withArguments:args
+ environment:environment
+ fileDescriptors:{0 . sout fileDescriptor . pipe second fileDescriptor}
+ fork:true
+ newPgrp:false
+ inDirectory:self workingDirectory.
+ ].
+
+ destination notNil ifTrue:[
+ Processor
+ monitor:exec
+ action:[:stat |
+ sema signal.
+ ].
+ ] ifFalse:[
+ exec value
+ ].
+
+
pipe second close.
+ sout close.
pid isNil ifTrue:[
HGCommandError raiseErrorString: 'cannot execute hg command'.
output close.
^ self.
].
- ^output
+ ^destination notNil
+ ifTrue:[sema wait. nil]
+ ifFalse:[output].
"Created: / 17-11-2012 / 00:13:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-12-2012 / 10:10:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!HGCommand::cat methodsFor:'private'!
--- a/mercurial/HGSourceCodeManager.st Tue Dec 04 01:36:59 2012 +0000
+++ b/mercurial/HGSourceCodeManager.st Tue Dec 04 10:14:28 2012 +0000
@@ -62,7 +62,38 @@
The classes source code is extracted using the revision and the sourceCodeInfo,
which itself is extracted from the classes packageString."
- ^ self shouldImplement
+ | pkg repo file |
+
+ pkg := HGPackageModel named: (moduleDir , ':' , packageDir).
+ repo := pkg repository.
+ file := (repo @ revision) / pkg repositoryRoot / classFileName.
+
+ doCache ifTrue:[
+ ^SourceCodeCache default
+ streamForClass:aClass
+ fileName:classFileName
+ revision:revision
+ repository: 'svn' "TODO: Use repository ID here"
+ module:moduleDir
+ directory:packageDir
+ ifAbsent: [:destination|
+ ActivityNotification notify: ('Checking out ', classFileName , '@' , revision , '...').
+ [
+ file copyTo: destination.
+ destination exists ifTrue:[
+ destination readStream
+ ] ifFalse:[
+ nil
+ ]
+ ] on: SVN::SVNError do:[
+ nil
+ ]
+ ]
+ ] ifFalse:[
+ ^file readStream.
+ ]
+
+ "Modified: / 04-12-2012 / 02:04:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!HGSourceCodeManager class methodsFor:'basic administration'!
@@ -148,12 +179,12 @@
Attention: if state = 'dead' that revision is no longer valid.
"
- | pkg repo path info newest |
+ | pkg repo path info newest rev limit stop log |
info := IdentityDictionary new.
- pkg := HGPackageModelRegistry packageNamed: (moduleDir , ':' , packageDir).
+ pkg := HGPackageModel named: (moduleDir , ':' , packageDir).
repo := pkg repository.
- path := repo repositoryRoot.
+ path := pkg repositoryRoot.
newest := repo workingCopy heads first.
[
@@ -169,13 +200,41 @@
info at:#filename put: classFileName. "/ -> the actual source file name
info at:#newestRevision put: newest id printString. "/-> the revisionString of the newest revision
- (rev1OrNil == 0 and:[rev2OrNil == 0]) ifTrue:[ ^ info ].
+ (rev1OrNil == 0 and:[rev2OrNil == 0]) ifTrue:[
+ limit := 1
+ ] ifFalse:[
+ limit := limitOrNil
+ ].
+ log := OrderedCollection new.
+ rev := rev1OrNil isNil ifTrue:[newest] ifFalse:[repo @ rev1OrNil].
+
+ stop := false.
+ [ stop ] whileFalse:[
+ | entry |
- self breakPoint: #jv.
+ entry := IdentityDictionary new.
+ entry at:#revision put: rev id printString."/ -> the revision string
+ entry at:#author put: rev author."/ -> who checked that revision into the repository
+ entry at:#date put: rev timestamp printString."/ -> when was it checked in
+ entry at:#state put: 'Exp'. "/ -> the RCS state
+ entry at:#numberOfChangedLines put: 'N/A'. "/ -> the number of changed line w.r.t the previous
+ entry at:#logMessage put: rev message."/ -> the checkIn log message.
+ log add: entry.
+
+ limit notNil ifTrue:[limit := limit - 1].
+ stop :=
+ rev isNil
+ or:[limit == 0
+ or:[(rev2OrNil notNil and:[rev2OrNil = rev id printString])
+ or:[([ rev / path / classFileName . false ] on: HGError do:[:ex | true ])]]].
+ rev := rev parent1.
+
+ ].
+ info at: #revisions put: log.
^info
- "Modified: / 01-12-2012 / 02:24:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-12-2012 / 01:34:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!HGSourceCodeManager class methodsFor:'queries'!
@@ -346,5 +405,5 @@
!
version_SVN
- ^ 'Id:: '
+ ^ '§Id:: §'
! !
--- a/mercurial/HGStXTests.st Tue Dec 04 01:36:59 2012 +0000
+++ b/mercurial/HGStXTests.st Tue Dec 04 10:14:28 2012 +0000
@@ -60,8 +60,16 @@
].
"/ Delay waitForSeconds: 1.
+ "/ Also, wipe out cached sources...
+ [
+ (AbstractSourceCodeManager cacheDirectoryName asFilename / 'mocks') recursiveRemove
+ ] on: Error do:[:ex|
+ Delay waitForSeconds: 1.
+ (AbstractSourceCodeManager cacheDirectoryName asFilename / 'mocks') recursiveRemove.
+ ]
+
"Created: / 16-11-2012 / 19:00:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 21-11-2012 / 17:53:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-12-2012 / 02:14:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
test_infrastructure
@@ -583,6 +591,110 @@
self assert: ((log at: #revisions) first at:#revision) = '0:99acfa83a3bf'.
"Created: / 04-12-2012 / 01:33:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_stream_01a
+
+ | stream repo contents |
+
+
+ repo := self repositoryNamed: 'mocks/hg/p1'.
+ self assert: (Smalltalk loadPackage:'mocks:hg/p1').
+
+ stream := HGSourceCodeManager
+ streamForClass:MockHGP1Bar
+ fileName:'MockHGP1Bar.st'
+ revision: '0:99acfa83a3bf'
+ directory: 'hg/p1'
+ module:'mocks'
+ cache: false.
+ contents := stream contents.
+
+ self assert: contents first = '"{ Package: ''mocks/hg/p1'' }"'
+
+ "Created: / 04-12-2012 / 02:04:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_stream_01b
+
+ | stream repo contents |
+
+
+ repo := self repositoryNamed: 'mocks/hg/p1'.
+ self assert: (Smalltalk loadPackage:'mocks:hg/p1').
+
+ stream := HGSourceCodeManager
+ streamForClass:MockHGP1Bar
+ fileName:'MockHGP1Bar.st'
+ revision: '1:e0bec585af86'
+ directory: 'hg/p1'
+ module:'mocks'
+ cache: false.
+ contents := stream contents.
+
+ self assert: contents first = '"{ Package: ''mocks:hg/p1'' }"'
+
+ "Created: / 04-12-2012 / 02:05:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_stream_02a
+
+ | stream repo contents |
+
+
+ repo := self repositoryNamed: 'mocks/hg/p1'.
+ self assert: (Smalltalk loadPackage:'mocks:hg/p1').
+
+ stream := HGSourceCodeManager
+ streamForClass:MockHGP1Bar
+ fileName:'MockHGP1Bar.st'
+ revision: '0:99acfa83a3bf'
+ directory: 'hg/p1'
+ module:'mocks'
+ cache: true.
+
+ contents := stream contents.
+
+ self assert: contents first = '"{ Package: ''mocks/hg/p1'' }"'.
+ self assert: stream isFileStream.
+
+ stream := HGSourceCodeManager
+ streamForClass:MockHGP1Bar
+ fileName:'MockHGP1Bar.st'
+ revision: '0:99acfa83a3bf'
+ directory: 'hg/p1'
+ module:'mocks'
+ cache: true.
+
+ contents := stream contents.
+
+ self assert: contents first = '"{ Package: ''mocks/hg/p1'' }"'.
+ self assert: stream isFileStream.
+
+ "Created: / 04-12-2012 / 02:08:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 04-12-2012 / 10:12:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_stream_02b
+
+ | stream repo contents |
+
+
+ repo := self repositoryNamed: 'mocks/hg/p1'.
+ self assert: (Smalltalk loadPackage:'mocks:hg/p1').
+
+ stream := HGSourceCodeManager
+ streamForClass:MockHGP1Bar
+ fileName:'MockHGP1Bar.st'
+ revision: '1:e0bec585af86'
+ directory: 'hg/p1'
+ module:'mocks'
+ cache: true.
+ contents := stream contents.
+
+ self assert: contents first = '"{ Package: ''mocks:hg/p1'' }"'
+
+ "Created: / 04-12-2012 / 10:11:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!HGStXTests methodsFor:'tests - misc'!
--- a/mercurial/mercurial.rc Tue Dec 04 01:36:59 2012 +0000
+++ b/mercurial/mercurial.rc Tue Dec 04 10:14:28 2012 +0000
@@ -25,7 +25,7 @@
VALUE "LegalCopyright", "Copyright Jan Vrany 2012\0"
VALUE "ProductName", "Smalltalk/X Mercurial Integration\0"
VALUE "ProductVersion", "6.2.3.0\0"
- VALUE "ProductDate", "Mon, 03 Dec 2012 16:17:54 GMT\0"
+ VALUE "ProductDate", "Tue, 04 Dec 2012 10:13:16 GMT\0"
END
END