--- a/FileBasedSourceCodeManager.st Thu Dec 22 10:00:31 2011 +0100
+++ b/FileBasedSourceCodeManager.st Thu Dec 22 10:00:33 2011 +0100
@@ -36,11 +36,12 @@
documentation
"
- Unfinished.
-
A simple file based sourceCodeManager, which saves versions in a local directory.
Versions will be stored as filename.st.vNr (i.e. Foo.st.1, Foo.st.2, etc.)
-
+
+ This is more an example of the protocol which needs to be implemented,
+ than a real manager (although it may be useful for tiny private projects or classroom examples)
+
[author:]
Claus Gittinger
"
@@ -48,6 +49,21 @@
!FileBasedSourceCodeManager class methodsFor:'accessing'!
+getRepositoryPathForModule:aModuleName
+ "internal: used when accessing a source repository.
+ Return the path to the top directory for a particular module.
+ If no specific path was defined for that module, return the value of
+ the global (fallBack) repositoryPath.
+ Nil is returned if no repository is available."
+
+ ModulePathes isNil ifTrue:[^ RepositoryPath].
+ aModuleName isNil ifTrue:[^ RepositoryPath].
+ ^ ModulePathes at:aModuleName ifAbsent:RepositoryPath.
+
+ "Modified: / 20-05-1998 / 16:30:12 / cg"
+ "Created: / 21-12-2011 / 23:05:51 / cg"
+!
+
knownModules
"return the modules, we currently know"
@@ -56,16 +72,50 @@
"Modified: / 21-12-2011 / 14:54:53 / cg"
!
+repositoryInfoPerModule
+ "return the dictionary, which associates repository pathes to module names.
+ If no entry is contained in this dictionary for some module,
+ the default path will be used."
+
+ ^ ModulePathes ? #()
+
+ "Created: / 22-12-2011 / 00:35:32 / cg"
+!
+
+repositoryInfoPerModule:aDictionary
+ "set the dictionary, which associates repository pathes to module names.
+ If no entry is contained in this dictionary for some module,
+ the default path will be used."
+
+ ModulePathes := aDictionary
+
+ "Created: / 22-12-2011 / 00:34:52 / cg"
+!
+
repositoryPath
"return the path of the default repository"
^ RepositoryPath
"Created: / 21-12-2011 / 14:55:12 / cg"
+!
+
+repositoryPath:aPath
+ "set the path of the default repository"
+
+ RepositoryPath := aPath
+
+ "Created: / 22-12-2011 / 00:30:19 / cg"
! !
!FileBasedSourceCodeManager class methodsFor:'queries'!
+defaultRepositoryPath
+ ^ './repository'
+
+ "Created: / 21-12-2011 / 23:59:52 / cg"
+!
+
enabled
^ true "/ false.
@@ -82,16 +132,10 @@
!
isResponsibleForPackage:aString
-
- | id |
-
- "JV@2011-07-09: The real check is too slow. Cache needed here"
- ^true.
-
-"/ id := aString asPackageId.
-"/ ^self checkForExistingModule: id module directory: id directory.
+ ^ true.
"Created: / 09-07-2011 / 14:32:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified (comment): / 22-12-2011 / 00:05:54 / cg"
!
managerTypeName
@@ -112,12 +156,12 @@
"Modified: / 21-12-2011 / 13:02:52 / cg"
!
-revisionInfoFromString:aString
- "{ Pragma: +optSpace }"
+repositoryNameForPackage:packageId
+ "superclass AbstractSourceCodeManager class says that I am responsible to implement this method"
- ^ nil
+ ^ self getRepositoryPathForModule:(packageId upTo:$: )
- "Created: / 21-12-2011 / 14:50:12 / cg"
+ "Created: / 21-12-2011 / 23:07:02 / cg"
!
settingsApplicationClass
@@ -140,21 +184,18 @@
!FileBasedSourceCodeManager class methodsFor:'saving'!
savePreferencesOn:aStream
-"/ aStream nextPutLine:'CVSSourceCodeManager notNil ifTrue:['.
-"/ self repositoryInfoPerModule notEmptyOrNil ifTrue:[
-"/ aStream nextPutLine:' CVSSourceCodeManager repositoryInfoPerModule:' , self repositoryInfoPerModule storeString , '.'.
-"/ ].
-"/ CVSExecutable notNil ifTrue:[
-"/ aStream nextPutLine:' CVSSourceCodeManager cvsExecutable:' , CVSExecutable storeString , '.'.
-"/ ].
-"/ (Smalltalk at:#SourceCodeManager) == self ifTrue:[
-"/ aStream nextPutLine:' Smalltalk at:#SourceCodeManager put: CVSSourceCodeManager.'.
-"/ aStream nextPutLine:' CVSSourceCodeManager initializeForRepository:' , self repositoryName storeString , '.'.
-"/ ].
-"/ aStream nextPutLine:'].'.
+ aStream nextPutLine:'FileBasedSourceCodeManager notNil ifTrue:['.
+ self repositoryInfoPerModule notEmptyOrNil ifTrue:[
+ aStream nextPutLine:' FileBasedSourceCodeManager repositoryInfoPerModule:' , self repositoryInfoPerModule storeString , '.'.
+ ].
+ (Smalltalk at:#SourceCodeManager) == self ifTrue:[
+ aStream nextPutLine:' Smalltalk at:#SourceCodeManager put:FileBasedSourceCodeManager.'.
+ ].
+ aStream nextPutLine:' FileBasedSourceCodeManager repositoryPath:' , self repositoryPath storeString , '.'.
+ aStream nextPutLine:'].'.
"Created: / 09-11-2006 / 15:09:25 / cg"
- "Modified: / 21-12-2011 / 13:03:30 / cg"
+ "Modified: / 22-12-2011 / 00:46:29 / cg"
! !
!FileBasedSourceCodeManager class methodsFor:'source code administration'!
@@ -294,12 +335,7 @@
|root|
- ModulePathes notNil ifTrue:[
- root := ModulePathes at:moduleDir ifAbsent:nil.
- ].
- root isNil ifTrue:[
- root := RepositoryPath.
- ].
+ root := self getRepositoryPathForModule:moduleDir.
root isNil ifTrue:[
RepositoryPath := root := './versions'.
].
@@ -320,28 +356,168 @@
"Created: / 21-12-2011 / 18:43:27 / cg"
!
+revisionInfoFromString:aString
+ "{ Pragma: +optSpace }"
+
+ "return a VersionInfo object filled with revision info.
+ This extracts the relevant info from aString."
+
+ |info path version user ts timeStamp idx1 idx2|
+
+ "/ 'Path: stx/libbasic/Array.st, Version: 123, User: cg, Time: 2011-12-21T21:03:08.826'
+
+ idx1 := aString indexOfSubCollection:'Path: '.
+ idx1 ~~ 0 ifTrue:[
+ idx1 := idx1 + 'Path: ' size.
+ idx2 := aString indexOfSubCollection:', ' startingAt:idx1.
+ path := aString copyFrom:idx1 to:idx2-1.
+ ].
+ idx1 := aString indexOfSubCollection:'Version: '.
+ idx1 ~~ 0 ifTrue:[
+ idx1 := idx1 + 'Version: ' size.
+ idx2 := aString indexOfSubCollection:', ' startingAt:idx1.
+ idx2 == 0 ifTrue:[
+ version := aString copyFrom:idx1
+ ] ifFalse:[
+ version := aString copyFrom:idx1 to:idx2-1.
+ ].
+ ].
+ idx1 := aString indexOfSubCollection:'User: '.
+ idx1 ~~ 0 ifTrue:[
+ idx1 := idx1 + 'User: ' size.
+ idx2 := aString indexOfSubCollection:', ' startingAt:idx1.
+ idx2 == 0 ifTrue:[
+ user := aString copyFrom:idx1
+ ] ifFalse:[
+ user := aString copyFrom:idx1 to:idx2-1.
+ ].
+ ].
+ idx1 := aString indexOfSubCollection:'Time: '.
+ idx1 ~~ 0 ifTrue:[
+ idx1 := idx1 + 'Time: ' size.
+ idx2 := aString indexOfSubCollection:', ' startingAt:idx1.
+ idx2 == 0 ifTrue:[
+ ts := aString copyFrom:idx1
+ ] ifFalse:[
+ ts := aString copyFrom:idx1 to:idx2-1.
+ ].
+ timeStamp := Timestamp readIso8601FormatFrom:ts
+ ].
+
+ info := VersionInfo new.
+ path notNil ifTrue:[ info fileName:(path asFilename baseName) ].
+ info revision:version.
+ user notNil ifTrue:[ info user:user ].
+ timeStamp notNil ifTrue:[ info timeStamp:timeStamp ].
+ ^ info
+
+ "
+ self revisionInfoFromString:'Path: stx/libbasic/Array.st, Version: 123, User: cg, Time: 2011-12-21T21:03:08.826'
+ "
+
+ "Created: / 21-12-2011 / 14:50:12 / cg"
+!
+
+revisionLogOf:clsOrNil fromRevision:rev1OrNil toRevision:rev2OrNil numberOfRevisions:limitOrNil fileName:classFileName directory:packageDir module:moduleDir
+ "Return true if ok, false if not."
+
+ |info log targetDir count newestRevision|
+
+ targetDir := self packageDirectoryForModule:moduleDir package:packageDir.
+ targetDir exists ifFalse:[^ nil ].
+
+ info := IdentityDictionary new.
+ log := OrderedCollection new.
+ count := 0.
+
+ (targetDir filesMatching:(classFileName,'_*')) do:[:eachVersionFile |
+ |versionString cs versionChange info|
+
+ versionString := eachVersionFile copyFrom:(classFileName size + 2).
+ count := count + 1.
+ (newestRevision isNil
+ or:[ self isRevision:versionString after:newestRevision ]) ifTrue:[
+ newestRevision := versionString
+ ].
+
+ (rev1OrNil isNil
+ or:[ rev1OrNil = 0
+ or:[ versionString = rev1OrNil
+ or:[ self isRevision:versionString after:rev1OrNil ]]])
+ ifTrue:[
+ (rev2OrNil isNil
+ or:[ rev2OrNil = 0
+ or:[ versionString = rev2OrNil
+ or:[ self isRevision:rev2OrNil after:versionString ]]])
+ ifTrue:[
+ (limitOrNil isNil
+ or:[ log size < limitOrNil ])
+ ifTrue:[
+ cs := ChangeSet fromFile:(targetDir construct:eachVersionFile).
+ versionChange := cs detect:[:chg | chg isMethodChange
+ and:[chg selector = self nameOfVersionMethodInClasses]]
+ ifNone:nil.
+ versionChange notNil ifTrue:[
+ info := self revisionInfoFromString:versionChange source.
+ ] ifFalse:[
+ info := VersionInfo new.
+ ].
+
+ info revision:versionString.
+ log add:info.
+ ]
+ ].
+ ].
+ ].
+ log sort:[:a :b | self isRevision:b revision after:a revision].
+
+ info at:#revisions put:log.
+ info at:#numberOfRevisions put:count.
+ info at:#newestRevision put:newestRevision.
+
+ ^ info
+
+ "Created: / 21-12-2011 / 20:39:31 / cg"
+!
+
revisionStringFor:aClass inModule:moduleDir directory:packageDir container:fileName revision:revisionString
"return a string usable as initial revision string"
- ^ 'Path: %1/%2/%3, Version: %4'
+ ^ 'Path: %1/%2/%3, Version: %4, User: %5, Time: %6'
bindWith:moduleDir
with:packageDir
with:fileName
with:revisionString
+ with:(OperatingSystem getLoginName)
+ with:(Timestamp now printStringIso8601Format)
+
+ "
+ self revisionStringFor:Array inModule:'stx' directory:'libbasic' container:'Array.st' revision:'123'
+ "
"Created: / 21-12-2011 / 19:33:33 / cg"
+!
+
+streamForClass:aClass fileName:classFileName revision:revision directory:packageDir module:moduleDir cache:doCache
+ |targetDir oldFile|
+
+ targetDir := self packageDirectoryForModule:moduleDir package:packageDir.
+ oldFile := (targetDir construct:classFileName,'_',revision).
+ ^ oldFile readStream
+
+ "Created: / 21-12-2011 / 20:49:01 / cg"
! !
!FileBasedSourceCodeManager class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic3/FileBasedSourceCodeManager.st,v 1.1 2011-12-21 18:42:42 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic3/FileBasedSourceCodeManager.st,v 1.2 2011-12-22 09:00:33 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic3/FileBasedSourceCodeManager.st,v 1.1 2011-12-21 18:42:42 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic3/FileBasedSourceCodeManager.st,v 1.2 2011-12-22 09:00:33 cg Exp $'
!
version_FileRepository
- ^ '§Path: stx/libbasic3/FileBasedSourceCodeManager.st, Version: 6§'
+ ^ '§Path: stx/libbasic3/FileBasedSourceCodeManager.st, Version: 13, User: cg, Time: 2011-12-22T00:40:40.985§'
! !