mercurial/HGChangesetFile.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Fri, 01 Feb 2013 12:02:22 +0000
changeset 210 54a73fa50d40
parent 190 a4a4b6f2fc52
child 278 4bacce9509fe
permissions -rw-r--r--
Added copyright notice.

"
 COPYRIGHT (c) 2012-2013 by Jan Vrany
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
"{ Package: 'stx:libscm/mercurial' }"

Object subclass:#HGChangesetFile
	instanceVariableNames:'changeset name parent children'
	classVariableNames:''
	poolDictionaries:''
	category:'SCM-Mercurial-Core'
!

!HGChangesetFile class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 2012-2013 by Jan Vrany
              All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

documentation
"
    A representation on a file in working copy. It behaves just like 
    ordinary filename but also provides methods for quering it's
    state (added/removed/modified...), access to previous versions
    and so on.

    The protocol of HGChangesetFile is Filename-like, however,
    no modification is allowed.

    [author:]
        Jan Vrany <jan.vrany@fit.cvut.cz>

    [instance variables:]

    [class variables:]

    [see also:]

"
! !

!HGChangesetFile methodsFor:'accessing'!

/ aString
    ^self construct: aString

    "Created: / 16-11-2012 / 23:47:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

baseName
    ^name

    "Created: / 17-11-2012 / 00:00:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

changeset
    ^ changeset
!

changesetId
    ^ changeset id

    "Created: / 22-01-2013 / 13:36:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

children
    ^ children
!

construct: aString
    "Returns a child name aString. If no such child
     exist, raise an error."

    | components file |

    ( aString includes: $/ ) ifTrue:[
        components := aString tokensBasedOn: $/.
    ] ifFalse:[
        ( aString includes: Filename separator ) ifTrue:[
            components := aString tokensBasedOn: Filename separator.
        ] ifFalse:[
            ^self childNamed: aString
        ]
    ].

    file := self.
    components do:[:each|file := file childNamed: each].
    ^file

    "Created: / 16-11-2012 / 23:47:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 01-12-2012 / 01:33:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

contents
    ^self readStream contents

    "Created: / 17-11-2012 / 00:02:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

directory
    ^parent

    "Created: / 16-11-2012 / 23:50:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

newer
    "Return newer revisions of given file based immediately on the recevier"

    ^self newer: false

    "Created: / 06-12-2012 / 00:09:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

newer: recursively
    "Return newer revisions of given file based on the recevier. If
     recursively is true, than all newer revisions are returned.
     otherwise only those based immediately on rhe receiver
    "

    | queue newer path |

    path := self pathName.
    queue := Stack withAll: (changeset children collect:[:e|Array with: e with: path]).
    newer := OrderedCollection new.

    [ queue notEmpty ] whileTrue:[
        | pair cs cont p |

        cs := queue top first.
        p := queue top second.
        queue pop.
        cont := true.
        cs changes do:[:chg|
            "/Catch renames...
            (chg isCopied and:[chg source = p]) ifTrue:[
                p := chg path.
            ].
            chg path = p ifTrue:[
                cont := false.
                chg isRemoved ifFalse:[
                    newer add: cs / p.
                ].
            ].
        ].
        (cont or:[recursively]) ifTrue:[
            queue addAll: (cs children collect:[:e|Array with: e with: p]).
        ].
    ].
    ^newer reversed

    "Created: / 06-12-2012 / 00:12:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

parent
    ^ parent
!

pathName
    ^String streamContents:[:s|self printPathOn: s].

    "Created: / 16-11-2012 / 23:55:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

readStream
    | rs |

    rs := HGCommand cat
            workingDirectory: self repository pathName;
            path: self pathName;
            revision: changeset id revno;
            execute.
    ^rs.

    "Created: / 17-11-2012 / 00:00:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 30-11-2012 / 23:36:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

repository
    ^self changeset repository

    "Created: / 17-11-2012 / 00:05:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile methodsFor:'accessing-private'!

childNamed: aString
    "Returns a child name aString. If no such child
     exist, raise an error."

    aString = '.' ifTrue:[ ^ self ].
    aString = '..' ifTrue:[ ^ parent ].


    children notNil ifTrue:[
        children at: aString ifPresent:[:child|^child].
    ].
    HGError newException
        parameter: (Array with: self with: aString );
        messageText: 'No such file or directory';
        raiseSignal.

    "Created: / 01-12-2012 / 01:29:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile methodsFor:'initialization'!

setChangeset: anHGChangeset name: aString
    ^self setChangeset: anHGChangeset name: aString parent: nil.

    "Created: / 16-11-2012 / 23:33:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

setChangeset: anHGChangeset name: aString parent: anHGChangesetFile
    changeset := anHGChangeset.
    name := aString.
    parent := anHGChangesetFile

    "Created: / 16-11-2012 / 23:50:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile methodsFor:'instance creation-private'!

create0: aString
    | file |

    aString isEmpty ifTrue:[ ^ self ].    
    children isNil ifTrue:[
        children := Dictionary new
    ] ifFalse:[
        children at: aString ifPresent:[:child|^child].
    ].
    file := self class new setChangeset: changeset name: aString parent: self.
    children at: aString put: file.
    ^file

    "Created: / 16-11-2012 / 23:41:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

create: aString
    | file |
    (aString includes: $/) ifTrue:[
        file := self.
        (aString tokensBasedOn: $/) do:[:each|
            file := file create0: each.            
        ]
    ] ifFalse:[
        file := self create0: aString
    ].
    ^file.

    "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
    "append a printed representation if the receiver to the argument, aStream"

    aStream nextPutAll:'anHGChangesetFile['.
    changeset id printOn: aStream.
    aStream space.
    self printPathOn: aStream.
    aStream nextPut:$].

    "Modified: / 06-12-2012 / 00:28:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

printPathOn: aStream
    parent notNil ifTrue:[
        parent printPathOn: aStream.
        parent parent notNil ifTrue:[
            aStream nextPut:$/.
        ].
    ].
    aStream nextPutAll: name.

    "Created: / 16-11-2012 / 23:53:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile methodsFor:'private'!

ensureNotLazy
    "Noop, I'm not lazy"

    "Created: / 22-01-2013 / 13:44:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile methodsFor:'testing'!

isHGChangesetId
    ^true

    "Created: / 22-01-2013 / 13:37:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!

isRootDirectory
    ^parent isNil

    "Created: / 16-11-2012 / 23:58:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !

!HGChangesetFile class methodsFor:'documentation'!

version_HG

    ^ '$Changeset: <not expanded> $'
! !