refactoring
authorClaus Gittinger <cg@exept.de>
Thu, 22 Dec 2011 10:00:33 +0100
changeset 2672 fa1b34f5b122
parent 2671 4ca06794fb1f
child 2673 06f4f56d7818
refactoring
FileBasedSourceCodeManager.st
--- 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§'
 ! !