OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart.io; | 5 part of dart.io; |
6 | 6 |
7 /** | 7 /** |
8 * [Link] objects are references to filesystem links. | 8 * [Link] objects are references to filesystem links. |
9 * | 9 * |
10 */ | 10 */ |
11 abstract class Link implements FileSystemEntity { | 11 abstract class Link implements FileSystemEntity { |
12 /** | 12 /** |
13 * Creates a Link object. | 13 * Creates a Link object. |
14 */ | 14 */ |
15 factory Link(String path) => new _Link(path); | 15 factory Link(String path) => new _Link(path); |
16 | 16 |
17 /** | 17 /** |
18 * Creates a symbolic link. Returns a [:Future<Link>:] that completes with | 18 * Creates a symbolic link. Returns a [:Future<Link>:] that completes with |
19 * the link when it has been created. If the link exists, | 19 * the link when it has been created. If the link exists, |
20 * the future will complete with an error. | 20 * the future will complete with an error. |
21 * | 21 * |
| 22 * If [recursive] is false, the default, the link is created |
| 23 * only if all directories in its path exist. |
| 24 * If [recursive] is true, all non-existing path |
| 25 * components are created. The directories in the path of [target] are |
| 26 * not affected, unless they are also in [path]. |
| 27 * |
22 * On the Windows platform, this will only work with directories, and the | 28 * On the Windows platform, this will only work with directories, and the |
23 * target directory must exist. The link will be created as a Junction. | 29 * target directory must exist. The link will be created as a Junction. |
24 * Only absolute links will be created, and relative paths to the target | 30 * Only absolute links will be created, and relative paths to the target |
25 * will be converted to absolute paths by joining them with the path of the | 31 * will be converted to absolute paths by joining them with the path of the |
26 * directory the link is contained in. | 32 * directory the link is contained in. |
27 * | 33 * |
28 * On other platforms, the posix symlink() call is used to make a symbolic | 34 * On other platforms, the posix symlink() call is used to make a symbolic |
29 * link containing the string [target]. If [target] is a relative path, | 35 * link containing the string [target]. If [target] is a relative path, |
30 * it will be interpreted relative to the directory containing the link. | 36 * it will be interpreted relative to the directory containing the link. |
31 */ | 37 */ |
32 Future<Link> create(String target); | 38 Future<Link> create(String target, {bool recursive: false}); |
33 | 39 |
34 /** | 40 /** |
35 * Synchronously create the link. Calling [createSync] on an existing link | 41 * Synchronously create the link. Calling [createSync] on an existing link |
36 * will throw an exception. | 42 * will throw an exception. |
37 * | 43 * |
| 44 * If [recursive] is false, the default, the link is created only if all |
| 45 * directories in its path exist. If [recursive] is true, all |
| 46 * non-existing path components are created. The directories in |
| 47 * the path of [target] are not affected, unless they are also in [path]. |
| 48 * |
38 * On the Windows platform, this will only work with directories, and the | 49 * On the Windows platform, this will only work with directories, and the |
39 * target directory must exist. The link will be created as a Junction. | 50 * target directory must exist. The link will be created as a Junction. |
40 * Only absolute links will be created, and relative paths to the target | 51 * Only absolute links will be created, and relative paths to the target |
41 * will be converted to absolute paths. | 52 * will be converted to absolute paths. |
42 * | 53 * |
43 * On other platforms, the posix symlink() call is used to make a symbolic | 54 * On other platforms, the posix symlink() call is used to make a symbolic |
44 * link containing the string [target]. If [target] is a relative path, | 55 * link containing the string [target]. If [target] is a relative path, |
45 * it will be interpreted relative to the directory containing the link. | 56 * it will be interpreted relative to the directory containing the link. |
46 */ | 57 */ |
47 void createSync(String target); | 58 void createSync(String target, {bool recursive: false}); |
48 | 59 |
49 /** | 60 /** |
50 * Synchronously updates the link. Calling [updateSync] on a non-existing link | 61 * Synchronously updates the link. Calling [updateSync] on a non-existing link |
51 * will throw an exception. | 62 * will throw an exception. |
52 * | 63 * |
53 * On the Windows platform, this will only work with directories, and the | 64 * On the Windows platform, this will only work with directories, and the |
54 * target directory must exist. | 65 * target directory must exist. |
55 */ | 66 */ |
56 void updateSync(String target); | 67 void updateSync(String target); |
57 | 68 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 Future<bool> exists() => FileSystemEntity.isLink(path); | 149 Future<bool> exists() => FileSystemEntity.isLink(path); |
139 | 150 |
140 bool existsSync() => FileSystemEntity.isLinkSync(path); | 151 bool existsSync() => FileSystemEntity.isLinkSync(path); |
141 | 152 |
142 Link get absolute => new Link(_absolutePath); | 153 Link get absolute => new Link(_absolutePath); |
143 | 154 |
144 Future<FileStat> stat() => FileStat.stat(path); | 155 Future<FileStat> stat() => FileStat.stat(path); |
145 | 156 |
146 FileStat statSync() => FileStat.statSync(path); | 157 FileStat statSync() => FileStat.statSync(path); |
147 | 158 |
148 Future<Link> create(String target) { | 159 Future<Link> create(String target, {bool recursive: false}) { |
149 if (Platform.operatingSystem == 'windows') { | 160 if (Platform.operatingSystem == 'windows') { |
150 target = _makeWindowsLinkTarget(target); | 161 target = _makeWindowsLinkTarget(target); |
151 } | 162 } |
152 return _IOService.dispatch(_FILE_CREATE_LINK, [path, target]) | 163 return (recursive ? parent.create(recursive: true) |
153 .then((response) { | 164 : new Future.value(null)) |
154 if (_isErrorResponse(response)) { | 165 .then((_) => _IOService.dispatch(_FILE_CREATE_LINK, [path, target])) |
155 throw _exceptionFromResponse( | 166 .then((response) { |
156 response, "Cannot create link to target '$target'", path); | 167 if (_isErrorResponse(response)) { |
157 } | 168 throw _exceptionFromResponse( |
158 return this; | 169 response, "Cannot create link to target '$target'", path); |
159 }); | 170 } |
| 171 return this; |
| 172 }); |
160 } | 173 } |
161 | 174 |
162 void createSync(String target) { | 175 void createSync(String target, {bool recursive: false}) { |
| 176 if (recursive) { |
| 177 parent.createSync(recursive: true); |
| 178 } |
163 if (Platform.operatingSystem == 'windows') { | 179 if (Platform.operatingSystem == 'windows') { |
164 target = _makeWindowsLinkTarget(target); | 180 target = _makeWindowsLinkTarget(target); |
165 } | 181 } |
166 var result = _File._createLink(path, target); | 182 var result = _File._createLink(path, target); |
167 throwIfError(result, "Cannot create link", path); | 183 throwIfError(result, "Cannot create link", path); |
168 } | 184 } |
169 | 185 |
170 // Put target into the form "\??\C:\my\target\dir". | 186 // Put target into the form "\??\C:\my\target\dir". |
171 String _makeWindowsLinkTarget(String target) { | 187 String _makeWindowsLinkTarget(String target) { |
172 Uri base = new Uri.file('${Directory.current.path}\\'); | 188 Uri base = new Uri.file('${Directory.current.path}\\'); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 return new ArgumentError(); | 285 return new ArgumentError(); |
270 case _OSERROR_RESPONSE: | 286 case _OSERROR_RESPONSE: |
271 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], | 287 var err = new OSError(response[_OSERROR_RESPONSE_MESSAGE], |
272 response[_OSERROR_RESPONSE_ERROR_CODE]); | 288 response[_OSERROR_RESPONSE_ERROR_CODE]); |
273 return new FileSystemException(message, path, err); | 289 return new FileSystemException(message, path, err); |
274 default: | 290 default: |
275 return new Exception("Unknown error"); | 291 return new Exception("Unknown error"); |
276 } | 292 } |
277 } | 293 } |
278 } | 294 } |
OLD | NEW |