6
6
from std/ paths import Path, ReadDirEffect, WriteDirEffect
7
7
8
8
from std/ private/ osfiles import fileExists, removeFile,
9
- moveFile
9
+ moveFile, copyFile, copyFileWithPermissions,
10
+ copyFileToDir, tryRemoveFile,
11
+ getFilePermissions, setFilePermissions,
12
+ CopyFlag, FilePermission
10
13
14
+ export CopyFlag, FilePermission
15
+
16
+
17
+ proc getFilePermissions* (filename: Path): set [FilePermission] {.inline, tags: [ReadDirEffect].} =
18
+ # # Retrieves file permissions for `filename`.
19
+ # #
20
+ # # `OSError` is raised in case of an error.
21
+ # # On Windows, only the ``readonly`` flag is checked, every other
22
+ # # permission is available in any case.
23
+ # #
24
+ # # See also:
25
+ # # * `setFilePermissions proc`_
26
+ result = getFilePermissions(filename.string )
27
+
28
+ proc setFilePermissions* (filename: Path, permissions: set [FilePermission],
29
+ followSymlinks = true )
30
+ {.inline, tags: [ReadDirEffect, WriteDirEffect].} =
31
+ # # Sets the file permissions for `filename`.
32
+ # #
33
+ # # If `followSymlinks` set to true (default) and ``filename`` points to a
34
+ # # symlink, permissions are set to the file symlink points to.
35
+ # # `followSymlinks` set to false is a noop on Windows and some POSIX
36
+ # # systems (including Linux) on which `lchmod` is either unavailable or always
37
+ # # fails, given that symlinks permissions there are not observed.
38
+ # #
39
+ # # `OSError` is raised in case of an error.
40
+ # # On Windows, only the ``readonly`` flag is changed, depending on
41
+ # # ``fpUserWrite`` permission.
42
+ # #
43
+ # # See also:
44
+ # # * `getFilePermissions proc`_
45
+ setFilePermissions(filename.string , permissions, followSymlinks)
11
46
12
47
proc fileExists* (filename: Path): bool {.inline, tags: [ReadDirEffect], sideEffect.} =
13
48
# # Returns true if `filename` exists and is a regular file or symlink.
14
49
# #
15
50
# # Directories, device files, named pipes and sockets return false.
16
51
result = fileExists(filename.string )
17
52
53
+ proc tryRemoveFile* (file: Path): bool {.inline, tags: [WriteDirEffect].} =
54
+ # # Removes the `file`.
55
+ # #
56
+ # # If this fails, returns `false`. This does not fail
57
+ # # if the file never existed in the first place.
58
+ # #
59
+ # # On Windows, ignores the read-only attribute.
60
+ # #
61
+ # # See also:
62
+ # # * `removeFile proc`_
63
+ result = tryRemoveFile(file.string )
64
+
18
65
proc removeFile* (file: Path) {.inline, tags: [WriteDirEffect].} =
19
66
# # Removes the `file`.
20
67
# #
@@ -26,6 +73,7 @@ proc removeFile*(file: Path) {.inline, tags: [WriteDirEffect].} =
26
73
# # See also:
27
74
# # * `removeDir proc <dirs.html#removeDir>`_
28
75
# # * `moveFile proc`_
76
+ # # * `tryRemoveFile proc`_
29
77
removeFile(file.string )
30
78
31
79
proc moveFile* (source, dest: Path) {.inline,
@@ -44,3 +92,73 @@ proc moveFile*(source, dest: Path) {.inline,
44
92
# # * `moveDir proc <dirs.html#moveDir>`_
45
93
# # * `removeFile proc`_
46
94
moveFile(source.string , dest.string )
95
+
96
+ proc copyFile* (source, dest: Path; options = cfSymlinkFollow; bufferSize = 16_384 ) {.inline, tags: [ReadDirEffect, ReadIOEffect, WriteIOEffect].} =
97
+ # # Copies a file from `source` to `dest`, where `dest.parentDir` must exist.
98
+ # #
99
+ # # On non-Windows OSes, `options` specify the way file is copied; by default,
100
+ # # if `source` is a symlink, copies the file symlink points to. `options` is
101
+ # # ignored on Windows: symlinks are skipped.
102
+ # #
103
+ # # If this fails, `OSError` is raised.
104
+ # #
105
+ # # On the Windows platform this proc will
106
+ # # copy the source file's attributes into dest.
107
+ # #
108
+ # # On other platforms you need
109
+ # # to use `getFilePermissions`_ and
110
+ # # `setFilePermissions`_
111
+ # # procs
112
+ # # to copy them by hand (or use the convenience `copyFileWithPermissions
113
+ # # proc`_),
114
+ # # otherwise `dest` will inherit the default permissions of a newly
115
+ # # created file for the user.
116
+ # #
117
+ # # If `dest` already exists, the file attributes
118
+ # # will be preserved and the content overwritten.
119
+ # #
120
+ # # On OSX, `copyfile` C api will be used (available since OSX 10.5) unless
121
+ # # `-d:nimLegacyCopyFile` is used.
122
+ # #
123
+ # # `copyFile` allows to specify `bufferSize` to improve I/O performance.
124
+ # #
125
+ # # See also:
126
+ # # * `copyFileWithPermissions proc`_
127
+ copyFile(source.string , dest.string , {options}, bufferSize)
128
+
129
+ proc copyFileWithPermissions* (source, dest: Path;
130
+ ignorePermissionErrors = true ,
131
+ options = cfSymlinkFollow) {.inline.} =
132
+ # # Copies a file from `source` to `dest` preserving file permissions.
133
+ # #
134
+ # # On non-Windows OSes, `options` specify the way file is copied; by default,
135
+ # # if `source` is a symlink, copies the file symlink points to. `options` is
136
+ # # ignored on Windows: symlinks are skipped.
137
+ # #
138
+ # # This is a wrapper proc around `copyFile`_,
139
+ # # `getFilePermissions`_ and `setFilePermissions`_
140
+ # # procs on non-Windows platforms.
141
+ # #
142
+ # # On Windows this proc is just a wrapper for `copyFile proc`_ since
143
+ # # that proc already copies attributes.
144
+ # #
145
+ # # On non-Windows systems permissions are copied after the file itself has
146
+ # # been copied, which won't happen atomically and could lead to a race
147
+ # # condition. If `ignorePermissionErrors` is true (default), errors while
148
+ # # reading/setting file attributes will be ignored, otherwise will raise
149
+ # # `OSError`.
150
+ # #
151
+ # # See also:
152
+ # # * `copyFile proc`_
153
+ copyFileWithPermissions(source.string , dest.string ,
154
+ ignorePermissionErrors, {options})
155
+
156
+ proc copyFileToDir* (source, dir: Path, options = cfSymlinkFollow; bufferSize = 16_384 ) {.inline.} =
157
+ # # Copies a file `source` into directory `dir`, which must exist.
158
+ # #
159
+ # # On non-Windows OSes, `options` specify the way file is copied; by default,
160
+ # # if `source` is a symlink, copies the file symlink points to. `options` is
161
+ # # ignored on Windows: symlinks are skipped.
162
+ # #
163
+ # # `copyFileToDir` allows to specify `bufferSize` to improve I/O performance.
164
+ copyFileToDir(source.string , dir.string , {options}, bufferSize)
0 commit comments