Eskil

Diff
Login

Differences From Artifact [230e217afb]:

To Artifact [312c085c71]:


35
36
37
38
39
40
41
42

43
44
45
46
47
48
49




50

51
52






53
54
55
56
57
58
59
35
36
37
38
39
40
41

42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69







-
+






-
+
+
+
+

+


+
+
+
+
+
+







    # a sub directory was given.
    # Locate fossil root for the given directory.
    set info [exec fossil info]
    regexp -line {local-root:\s*(\S.*)} $info -> root
    set root [file normalize $root]
    cd $root

    # Getting files via artifact
    # Getting files via manifest artifact
    # This is a quick and robust way to get the file tree and each file's sha
    # Other info is trickier and is handled below
    set artifact [exec fossil artifact $rev]
    set commitTime 0
    set cTime now
    set finfo {}
    foreach line [split $artifact \n] {
    set todo [split $artifact \n]
    while {[llength $todo] > 0} {
        set line [lindex $todo 0]
        set todo [lrange $todo 1 end]
        # Expected format in a line:
        # B baseline
        # F tests/left.txt c1572b3809a1ba6ab2de9307c96b1cfeefdcf0ba
        # D 2015-02-23T23:30:07.509
        if {[regexp {B (.*)} $line -> bUuid]} {
            # Pick up a baseline manifest and parse it first
            set artifact [exec fossil artifact $bUuid]
            set todo [concat [split $artifact \n] $todo]
            continue
        }
        if {[regexp {D (.*)} $line -> cTime]} {
            # Remove decimals and middle T
            regsub {\.\d+} $cTime "" cTime
            regsub {T} $cTime " " cTime
            set commitTime [clock scan $cTime -gmt 1]
        }
        if {[regexp {F (\S+) (\S+)} $line -> fName fSha]} {
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480


481
482
483
484
485
486
487
488
489
490

491
492
493
494
495


496
497
498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513
514
515


516
517
518
519
520
521
522
523
524
525
526
527
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488


489
490


491
492

493
494
495
496

497
498
499
500


501
502


503
504

505
506
507
508

509
510
511

512
513
514
515
516


517
518


519
520

521
522
523
524
525
526
527







-
+








-
-
+
+
-
-


-




-
+



-
-
+
+
-
-


-




-
+


-





-
-
+
+
-
-


-







        if {[dict get $finfo $local isdir] && !$allowDir} continue
        lappend result [file join $actual $child]
    }
    return $result
}

# Extract file data from Fossil revision
proc vcsvfs::fossil::openFile {rootD relative} {
proc vcsvfs::fossil::openFile {rootD relative mode} {
    set oldpwd [pwd]
    cd [dict get $rootD "origroot"]
    set rev [dict get $rootD rev]
    # Which way of extracting file data is best?
    # fossil finfo -p -r $rev $relative
    # set sha [dict get $finfor sha]
    # fossil artifact $sha
    # fossil cat $relative -r $rev
    # Read through a pipe to get a binary channel
    set chId [open [list |fossil cat $relative -r $rev] rb]
    # Read through a pipe to get requested mode
    set chId [open [list |fossil cat $relative -r $rev] $mode]
    #set data [read $chId]
    #close $chId
    cd $oldpwd

    #set chId [vcsvfs::CreateDataRefChan $data]
    return [list $chId [list vcsvfs::ReadAllBeforeClose $chId]]
}

# Extract file data from Subversion revision
proc vcsvfs::svn::openFile {rootD relative} {
proc vcsvfs::svn::openFile {rootD relative mode} {
    set oldpwd [pwd]
    cd [dict get $rootD "origroot"]
    set rev [dict get $rootD rev]
    # Read through a pipe to get a binary channel
    set chId [open [list |svn cat -r $rev $relative] rb]
    # Read through a pipe to get requested mode
    set chId [open [list |svn cat -r $rev $relative] $mode]
    #set data [read $chId]
    #close $chId
    cd $oldpwd

    #set chId [vcsvfs::CreateDataRefChan $data]
    return [list $chId [list vcsvfs::ReadAllBeforeClose $chId]]
}

# Some notes about git commands that can be good to have
proc vcsvfs::git::openFile {rootD relative} {
proc vcsvfs::git::openFile {rootD relative mode} {
    set oldpwd [pwd]
    cd [dict get $rootD "origroot"]
    set rev [dict get $rootD rev]
    set sha [dict get $rootD finfo $relative sha]
    #git cat-file
    #git show <rev>^{tree}
    # example: git show HEAD^^^:apa

    # Read through a pipe to get a binary channel
    set chId [open [list |git cat-file blob $sha] rb]
    # Read through a pipe to get requested mode
    set chId [open [list |git cat-file blob $sha] $mode]
    #set data [read $chId]
    #close $chId
    cd $oldpwd

    #set chId [vcsvfs::CreateDataRefChan $data]
    return [list $chId [list vcsvfs::ReadAllBeforeClose $chId]]
}

# Fossil may delay filling in size, this takes car of that
proc vcsvfs::fossil::size {finfo} {
    # Use "fossil whatis" on its sha
    # Expected format in a line:
590
591
592
593
594
595
596
597

598
599
600
601
602
603

604
605
606
607
608
609
610
590
591
592
593
594
595
596

597
598
599
600
601
602

603
604
605
606
607
608
609
610







-
+





-
+







        matchindirectory {
            return [vcsvfs::MatchInDirectory $finfo $relative $actual {*}$args]
        }
        open {
            set mode [lindex $args 0]
            if {$mode == {}} {set mode r}
            #set permissions [lindex $args 1]
            if {$mode ne "r"} {
            if {$mode ne "r" && $mode ne "rb"} {
                # Read only
                vfs::filesystem posixerror $::vfs::posix(EACCES)
                return -code error $::vfs::posix(EACCES)
            }

            return [vcsvfs::${vcstype}::openFile $rootD $relative]
            return [vcsvfs::${vcstype}::openFile $rootD $relative $mode]
        }
        stat {
            set res [dict create dev 0 ino 0 "mode" 0 nlink 0 uid 0 gid 0 \
                             size 0 atime 0 mtime 0 ctime 0 type file]
            dict set res type [dict get $finfor type]
            if {[dict get $finfor isfile]} {
                # Fill in any postponed info