File: FetchPath.rakumod

package info (click to toggle)
raku-zef 0.13.8-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 664 kB
  • sloc: perl: 22; makefile: 8
file content (139 lines) | stat: -rw-r--r-- 5,444 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use Zef;
use Zef::Utils::FileSystem;

class Zef::Service::FetchPath does Fetcher does Extractor does Messenger {

    =begin pod

    =title class Zef::Service::FetchPath

    =subtitle A file system based implementation of the Fetcher and Extractor interfaces

    =head1 Synopsis

    =begin code :lang<raku>

        use Zef;
        use Zef::Service::FetchPath;

        my $fetch-path = Zef::Service::FetchPath.new;

        # Copy the content of the current directory to ./backup_dir/$random/*
        my $source   = $*CWD;
        my $save-to  = $*CWD.child("backup_dir");
        my $saved-to = $fetch-path.fetch($source, $save-to);

        die "Failed to copy paths" unless $saved-to;
        say "The following top level paths now exist:";
        say "\t{$_.Str}" for $saved-to.dir;

        my $extract-to   = $*CWD.child("extracted_backup_dir");
        my $extracted-to = $fetch-path.extract($saved-to, $extract-to);

        die "Failed to extract paths" unless $extracted-to;
        say "The following top level paths now exist:";
        say "\t{$_.Str}" for $extracted-to.dir;

    =end code

    =head1 Description

    C<Fetcher> and C<Extractor> class for handling local file paths.

    You probably never want to use this unless its indirectly through C<Zef::Fetch> or C<Zef::Extractor>;
    handling files will generally be easier using core language functionality. This class exists to provide
    the means for fetching local paths using the C<Fetcher> and C<Extractor> interfaces that the e.g. git/http/tar
    fetching/extracting adapters use.

    =head1 Methods

    =head2 method probe

        method probe(--> Bool:D)

    Returns C<True> if this module believes all run time prerequisites are met. Since the only prerequisite
    is a file system this always returns C<True>

    =head2 method fetch-matcher

        method fetch-matcher(Str() $uri --> Bool:D) 

    Returns C<True> if this module knows how to fetch C<$uri>, which it decides based on if C<$uri> looks like
    a file path (i.e. C<$uri> starts with a C<.> or C</>) and if that file path exists.

    =head2 method extract-matcher

        method extract-matcher(Str() $uri --> Bool:D) 

    Returns C<True> if this module knows how to extract C<$uri>, which it decides based on if C<$uri> looks like
    a file path (i.e. C<$uri> starts with a C<.> or C</>) and if that file path exists as a directory.

    =head2 method fetch

        method fetch(IO() $source-path, IO() $save-to --> IO::Path)

    Fetches the given C<$source-path> from the file system and copies it to C<$save-to> (+ timestamp if C<$source-path>
    is a directory) directory.

    On success it returns the C<IO::Path> where the data was actually saved to (usually a subdirectory under the passed-in
    C<$save-to>). On failure it returns C<Nil>.

    =head2 method extract

        method extract(IO() $source-path, IO() $save-to --> IO::Path)

    Extracts the given C<$source-path> from the file system and copies it to C<$save-to>.

    On success it returns the C<IO::Path> where the data was actually extracted to. On failure it returns C<Nil>.

    =head2 method ls-files

        method ls-files(IO() $path --> Array[Str])

    On success it returns an C<Array> of relative paths that are available to be extracted from C<$path>.

    =end pod


    #| Always return true since a file system is required
    method probe(--> Bool:D) { return True }

    #| Return true if this Fetcher understands the given uri/path
    method fetch-matcher(Str() $uri --> Bool:D) {
        # .is-absolute lets the app pass around absolute paths on windows and still work as expected
        my $is-pathy = so <. />.first({ $uri.starts-with($_) }) || $uri.IO.is-absolute;
        return so $is-pathy && $uri.IO.e;
    }

    #| Return true if this Extractor understands the given uri/path
    method extract-matcher(Str() $uri --> Bool:D) {
        # .is-absolute lets the app pass around absolute paths on windows and still work as expected
        my $is-pathy = so <. />.first({ $uri.starts-with($_) }) || $uri.IO.is-absolute;
        return so $is-pathy && $uri.IO.d;
    }

    #| Fetch (copy) the given source path to the $save-to (+ timestamp if source-path is a directory) directory
    method fetch(IO() $source-path, IO() $save-to --> IO::Path) {
        return Nil if !$source-path.e;
        return $source-path if $source-path.absolute eq $save-to.absolute; # fakes a fetch
        my $dest-path = $source-path.d ?? $save-to.child("{$source-path.IO.basename}_{time}") !! $save-to;
        mkdir($dest-path) if $source-path.d && !$save-to.e;
        return $dest-path if copy-paths($source-path, $dest-path).elems;
        return Nil;
    }

    #| Extract (copy) the files located in $source-path directory to $save-to directory.
    #| This is mostly the same as fetch, and essentially allows the workflow to treat
    #| any uri type (including paths) as if they can be extracted.
    method extract(IO() $source-path, IO() $save-to --> IO::Path) {
        my $extracted-to = $save-to.child($source-path.basename);
        my @extracted = copy-paths($source-path, $extracted-to);
        return +@extracted ?? $extracted-to !! Nil;
    }

    #| List all files and directories, recursively, for the given path
    method ls-files(IO() $path --> Array[Str]) {
        my Str @results = list-paths($path, :f, :!d, :r).map(*.Str);
        return @results;
    }
}