Added support for ancestry splicemaps. jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Tue, 08 Sep 2015 01:03:02 +0100
branchjv
changeset 1004 e48adfaf3541
parent 1003 0ebeea1cdeeb
child 1005 fe6be0a71dbe
Added support for ancestry splicemaps. A splicemap may be used by other version control systems to forge MC ancestors when generating MC version info out of its own version history. MC versions found in splicemap may be added to particular commits and thus 'connect' both MC and 'the other SCM' histories, which are otherwise disjunct. The goal is to make merging using Monticello tools easier by giving them a chance to find a common ancestor. This is currently used by Mercurial when exporting .mcz.
MCRepositoryBrowser.st
MCVersionInfo.st
MCVersionInfoWriter.st
Make.proto
bc.mak
extensions.st
stx_goodies_monticello.st
--- a/MCRepositoryBrowser.st	Mon Sep 07 16:13:08 2015 +0100
+++ b/MCRepositoryBrowser.st	Tue Sep 08 01:03:02 2015 +0100
@@ -598,9 +598,16 @@
             itemValue: versionCompareWithImage
           )
          (MenuItem
-            enabled: false
-            label: 'Merge'
-            itemValue: versionMerge
+            label: '-'
+          )
+         (MenuItem
+            label: 'Update Code...'
+            itemValue: versionUpdateCode
+          )
+         (MenuItem
+            enabled: canUpdateSplicemap
+            label: 'Update Splicemap...'
+            itemValue: versionUpdateSplicemap
           )
          (MenuItem
             label: '-'
@@ -737,6 +744,12 @@
 
 !MCRepositoryBrowser methodsFor:'aspect-queries'!
 
+canUpdateSplicemap
+    ^ ConfigurableFeatures hasMercurialSupport
+
+    "Created: / 08-09-2015 / 00:56:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 hasRepositorySelectedHolder
     ^ BlockValue
         with:[:h | h value notNil]
@@ -1219,7 +1232,7 @@
 
 versionCompareWithImage
 
-    | version package snapshot snapshotCS packageCS diffset diffCS |
+    | version package snapshot snapshotCS |
 
     self withWaitCursorDo:[
         version := self selectedVersionAsMCVersion.
@@ -1235,6 +1248,17 @@
         ].
         package := Dialog requestProject:(resources string: 'Package to compare with') initialAnswer:package suggestions: nil.
         package isNil ifTrue:[ ^ self ].
+        self versionCompareWithImagePackage: package.  
+    ].
+
+    "Modified: / 07-09-2015 / 18:41:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+versionCompareWithImagePackage: package
+
+    | version snapshotCS packageCS diffset diffCS |
+
+    self withWaitCursorDo:[
         packageCS := ChangeSet forPackage: package.
         "/ Remove St/X specific method and classes (used for package management)
         packageCS := packageCS reject:[:chg |  
@@ -1266,7 +1290,7 @@
             open       
     ].
 
-    "Modified: / 30-04-2015 / 21:53:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 07-09-2015 / 18:41:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 versionInspect
@@ -1359,6 +1383,68 @@
 
     "Modified: / 09-11-2010 / 13:33:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 07-09-2011 / 12:47:51 / cg"
+!
+
+versionUpdateCode
+
+    | version package snapshot snapshotCS |
+
+    self withWaitCursorDo:[
+        version := self selectedVersionAsMCVersion.
+        version isNil ifTrue:[ ^ self ].
+        snapshot := version snapshot.
+        snapshotCS := snapshot asChangeSet.
+        snapshotCS name: version info name.
+        ProjectDefinition allSubclassesDo:[ :def |
+            ((def class compiledMethodAt: #monticelloName) notNil and:[
+                def monticelloName = version package name]) ifTrue:[ 
+                package := def package.
+            ].
+        ].
+        package isNil ifTrue:[ 
+            Dialog warn: (resources string: 'No package found for Monticello package ''%1''' with: version package name).
+            ^ self
+        ].
+        self versionCompareWithImagePackage: package.  
+    ].
+
+    "Created: / 07-09-2015 / 18:36:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+versionUpdateSplicemap
+
+    | version package dialog revset packageDef splicemap |
+
+    self withWaitCursorDo:[
+        version := self selectedVersionAsMCVersion.
+        version isNil ifTrue:[ ^ self ].
+        ProjectDefinition allSubclassesDo:[ :def |
+            ((def class compiledMethodAt: #monticelloName) notNil and:[
+                def monticelloName = version package name]) ifTrue:[ 
+                package := def package.
+                packageDef := def.
+            ].
+        ].
+        package isNil ifTrue:[ 
+            Dialog warn: (resources string: 'No package found for Monticello package ''%1''' with: version package name).
+            ^ self
+        ].
+        revset := 'grep(''%1'')' bindWith: version info name.
+
+        dialog := HGChangesetDialog new.
+        dialog repository: (HGPackageWorkingCopy named:package) repository .
+        dialog revset: revset asHGRevset.
+        dialog open ifFalse:[ ^ self ].
+        splicemap := { dialog changeset id literalArrayEncoding . version info literalArrayEncodingWithoutAncestors } 
+                        , packageDef monticelloSplicemap.
+        packageDef theMetaclass 
+                compile: (packageDef monticelloSplicemap_codeFor:splicemap)
+                classified:(packageDef class lookupMethodFor: #monticelloSplicemap) category
+
+    ].
+
+    "Created: / 07-09-2015 / 18:37:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-09-2015 / 00:07:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !MCRepositoryBrowser methodsFor:'updating'!
--- a/MCVersionInfo.st	Mon Sep 07 16:13:08 2015 +0100
+++ b/MCVersionInfo.st	Tue Sep 08 01:03:02 2015 +0100
@@ -137,6 +137,53 @@
 		at: #author put: author;
 		at: #ancestors put: (self ancestors collect: [:a | a asDictionary]);
 		yourself
+!
+
+fromLiteralArrayEncoding: encoding
+    name := encoding at: 3.
+    id := UUID fromString: (encoding at: 5).
+    date := Date readFrom:(encoding at: 7) format: '%y-%m-%d'.
+    time := Time readFrom:(encoding at: 9) format: '%H:%m:%s.%i'.
+    author :=  encoding at: 11.
+    message := (encoding at: 13) asStringWithSqueakLineEndings.     
+    encoding size > 13 ifTrue:[
+        ancestors := (encoding at: 15) collect:[ :e | e decodeAsLiteralArray ].
+    ].
+
+    "Created: / 07-09-2015 / 17:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-09-2015 / 00:02:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+literalArrayEncoding
+    ^ self literalArrayEncodingWithAncestors: true
+
+    "Created: / 07-09-2015 / 17:23:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+literalArrayEncodingWithAncestors: withAncestors
+    | encoding |
+    encoding := Array new: 13 + (withAncestors ifTrue:[2] ifFalse:[0]).
+    encoding
+        at: 1 put: MCVersionInfo name;
+        at: 2 put: #name:; at: 3 put: name;
+        at: 4 put: #id:; at: 5 put: id printString;
+        at: 6 put: #date:; at: 7 put: (date printStringFormat:'%y-%m-%d');
+        at: 8 put: #time:; at: 9 put: (time printStringFormat:'%H:%m:%s.%i');
+        at:10 put: #author:; at: 11 put: author;
+        at:12 put: #message:; at: 13 put: (message asStringWithNativeLineEndings).
+    withAncestors ifTrue:[    
+        encoding at:14 put: #ancestors:; at: 15 put: (withAncestors ifTrue:[self ancestors collect:[ :e|e literalArrayEncodingWithAncestors: withAncestors ] as: Array] ifFalse:[ #() ]).
+    ].
+    ^ encoding.
+
+    "Created: / 07-09-2015 / 17:22:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-09-2015 / 00:00:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+literalArrayEncodingWithoutAncestors
+    ^ self literalArrayEncodingWithAncestors: false
+
+    "Created: / 07-09-2015 / 17:47:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !MCVersionInfo methodsFor:'initialize-release'!
--- a/MCVersionInfoWriter.st	Mon Sep 07 16:13:08 2015 +0100
+++ b/MCVersionInfoWriter.st	Tue Sep 08 01:03:02 2015 +0100
@@ -13,7 +13,9 @@
 !MCVersionInfoWriter methodsFor:'as yet unclassified'!
 
 isWritten: aVersionInfo
-	^ self written includes: aVersionInfo
+        ^ self written includes: aVersionInfo id
+
+    "Modified: / 08-09-2015 / 00:19:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 writeVersionInfo: aVersionInfo
@@ -50,7 +52,9 @@
 !
 
 wrote: aVersionInfo
-	self written add: aVersionInfo
+        self written add: aVersionInfo id
+
+    "Modified: / 08-09-2015 / 00:19:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !MCVersionInfoWriter class methodsFor:'documentation'!
--- a/Make.proto	Mon Sep 07 16:13:08 2015 +0100
+++ b/Make.proto	Tue Sep 08 01:03:02 2015 +0100
@@ -34,7 +34,7 @@
 # add the path(es) here:,
 # ********** OPTIONAL: MODIFY the next lines ***
 # LOCALINCLUDES=-Ifoo -Ibar
-LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/communication -I$(INCLUDE_TOP)/stx/libbasic -I$(INCLUDE_TOP)/stx/libbasic2 -I$(INCLUDE_TOP)/stx/libbasic3 -I$(INCLUDE_TOP)/stx/libcomp -I$(INCLUDE_TOP)/stx/libcompat -I$(INCLUDE_TOP)/stx/libhtml -I$(INCLUDE_TOP)/stx/libtool -I$(INCLUDE_TOP)/stx/libview -I$(INCLUDE_TOP)/stx/libview2 -I$(INCLUDE_TOP)/stx/libwidg -I$(INCLUDE_TOP)/stx/libwidg2
+LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/communication -I$(INCLUDE_TOP)/stx/libbasic -I$(INCLUDE_TOP)/stx/libbasic2 -I$(INCLUDE_TOP)/stx/libbasic3 -I$(INCLUDE_TOP)/stx/libcomp -I$(INCLUDE_TOP)/stx/libcompat -I$(INCLUDE_TOP)/stx/libhtml -I$(INCLUDE_TOP)/stx/libscm/mercurial -I$(INCLUDE_TOP)/stx/libtool -I$(INCLUDE_TOP)/stx/libview -I$(INCLUDE_TOP)/stx/libview2 -I$(INCLUDE_TOP)/stx/libwidg -I$(INCLUDE_TOP)/stx/libwidg2
 
 
 # if you need any additional defines for embedded C code,
--- a/bc.mak	Mon Sep 07 16:13:08 2015 +0100
+++ b/bc.mak	Tue Sep 08 01:03:02 2015 +0100
@@ -35,7 +35,7 @@
 
 
 
-LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\communication -I$(INCLUDE_TOP)\stx\libbasic -I$(INCLUDE_TOP)\stx\libbasic2 -I$(INCLUDE_TOP)\stx\libbasic3 -I$(INCLUDE_TOP)\stx\libcomp -I$(INCLUDE_TOP)\stx\libcompat -I$(INCLUDE_TOP)\stx\libhtml -I$(INCLUDE_TOP)\stx\libtool -I$(INCLUDE_TOP)\stx\libview -I$(INCLUDE_TOP)\stx\libview2 -I$(INCLUDE_TOP)\stx\libwidg -I$(INCLUDE_TOP)\stx\libwidg2
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\communication -I$(INCLUDE_TOP)\stx\libbasic -I$(INCLUDE_TOP)\stx\libbasic2 -I$(INCLUDE_TOP)\stx\libbasic3 -I$(INCLUDE_TOP)\stx\libcomp -I$(INCLUDE_TOP)\stx\libcompat -I$(INCLUDE_TOP)\stx\libhtml -I$(INCLUDE_TOP)\stx\libscm\mercurial -I$(INCLUDE_TOP)\stx\libtool -I$(INCLUDE_TOP)\stx\libview -I$(INCLUDE_TOP)\stx\libview2 -I$(INCLUDE_TOP)\stx\libwidg -I$(INCLUDE_TOP)\stx\libwidg2
 LOCALDEFINES=
 
 STCLOCALOPT=-package=$(PACKAGE) -I. $(LOCALINCLUDES) -headerDir=. $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES)  -varPrefix=$(LIBNAME)
--- a/extensions.st	Mon Sep 07 16:13:08 2015 +0100
+++ b/extensions.st	Tue Sep 08 01:03:02 2015 +0100
@@ -207,6 +207,65 @@
     "Created: / 07-06-2013 / 01:48:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!ProjectDefinition class methodsFor:'accessing - monticello'!
+
+monticelloSplicemap
+    "Return a splicemap for this package. This is used to forge a 
+     'fake' ancestor when generating ancestry information out of 
+     Mercurial (or anyt other) history. This should make merging 
+     back into Squeak/Pharo a little easier as Monticello can (in theory)
+     find a proper ancestor. 
+
+     All this requires monticelloSplicemap being updated each time a code
+     is merged from Monticello.
+
+     The format of splicemap is a flat array of pairs 
+     (commit id, MCVersionInfo to splice) as literal encoding.
+    "
+    ^#()
+
+    "Created: / 07-09-2015 / 18:11:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ProjectDefinition class methodsFor:'code generation'!
+
+monticelloSplicemap_code
+    ^ self monticelloSplicemap_codeFor:self monticelloSplicemap
+
+    "Created: / 07-09-2015 / 17:58:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ProjectDefinition class methodsFor:'code generation'!
+
+monticelloSplicemap_codeFor:splicemap 
+    ^ String 
+        streamContents:[:s | 
+            s nextPutLine:'monticelloSplicemap'.
+            s
+                nextPutAll:'    "';
+                nextPutAll:(self class superclass lookupMethodFor:#monticelloSplicemap) 
+                            comment;
+                nextPutLine:'"'.
+            s nextPutLine:''.
+            s nextPutLine:'    ^ #('.
+            splicemap 
+                pairWiseDo:[:changeset :mcversion | 
+                    s nextPutAll:'        '.
+                    changeset storeOn:s.
+                    s space.
+                    mcversion storeOn:s.
+                    s
+                        cr;
+                        cr.
+                ].
+            s nextPutLine:'    )'
+        ].
+
+    "
+     stx_goodies_petitparser_compiler monticelloSplicemap_code"
+    "Created: / 07-09-2015 / 17:58:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !ProjectDefinition class methodsFor:'code generation'!
 
 monticelloTimestamps_code
--- a/stx_goodies_monticello.st	Mon Sep 07 16:13:08 2015 +0100
+++ b/stx_goodies_monticello.st	Tue Sep 08 01:03:02 2015 +0100
@@ -65,6 +65,7 @@
         #'stx:libbasic2'    "Iterator - referenced by MCPackageList>>makeGenerator"
         #'stx:libcomp'    "Parser - referenced by MCRepositoryBrowser>>repositoryAddFromExpressionString"
         #'stx:libhtml'    "HTMLDocumentView - referenced by MCRepositoryBrowser>>openDocumentation"
+        #'stx:libscm/mercurial'    "HGChangesetDialog - referenced by MCRepositoryBrowser>>versionUpdateSplicemap"
         #'stx:libview'    "Color - referenced by MCCommitDialog>>findUniqueVersionNumber"
         #'stx:libwidg'    "PopUpMenu - referenced by MCVersionInspector>>pickAncestor"
     )
@@ -268,6 +269,9 @@
         CharacterArray asStringWithSqueakLineEndings
         CharacterArray asStringWithNativeLineEndings
         'ProjectDefinition class' monticelloNameForMCZ
+        'ProjectDefinition class' monticelloSplicemap
+        'ProjectDefinition class' #'monticelloSplicemap_code'
+        'ProjectDefinition class' #'monticelloSplicemap_codeFor:'
     )
 ! !