diff options
| author | diogo464 <[email protected]> | 2021-07-09 04:15:11 -0400 |
|---|---|---|
| committer | diogo464 <[email protected]> | 2021-07-09 04:15:11 -0400 |
| commit | f13a60805df476649e908842f78785ccf47834ed (patch) | |
| tree | 486d5d93e7876248aae1bd853b4977eb7f432cd4 | |
| parent | e1df098c885bda5cd0b375cb46c460367abe4f17 (diff) | |
Allow linking directories.
| -rw-r--r-- | dotup/src/depot.rs | 33 | ||||
| -rw-r--r-- | dotup_cli/src/commands/link.rs | 8 |
2 files changed, 40 insertions, 1 deletions
diff --git a/dotup/src/depot.rs b/dotup/src/depot.rs index 227d824..0e987d2 100644 --- a/dotup/src/depot.rs +++ b/dotup/src/depot.rs | |||
| @@ -20,6 +20,10 @@ pub enum LinkCreateError { | |||
| 20 | LinkPathIsNotRelative(PathBuf), | 20 | LinkPathIsNotRelative(PathBuf), |
| 21 | #[error("Link origin doesnt exist : {}", .0.display())] | 21 | #[error("Link origin doesnt exist : {}", .0.display())] |
| 22 | LinkOriginDoesntExist(PathBuf), | 22 | LinkOriginDoesntExist(PathBuf), |
| 23 | #[error("Cannot create link for directory {} beacause it has a linked child", .0.display())] | ||
| 24 | DirectoryHasLinkedChildren(PathBuf), | ||
| 25 | #[error("Cannot create link for file {} beacause it has a linked parent", .0.display())] | ||
| 26 | FileHasLinkedParent(PathBuf), | ||
| 23 | #[error(transparent)] | 27 | #[error(transparent)] |
| 24 | IOError(#[from] std::io::Error), | 28 | IOError(#[from] std::io::Error), |
| 25 | } | 29 | } |
| @@ -82,9 +86,16 @@ impl From<ArchiveLink> for LinkCreateParams { | |||
| 82 | } | 86 | } |
| 83 | } | 87 | } |
| 84 | 88 | ||
| 89 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
| 90 | enum LinkType { | ||
| 91 | File, | ||
| 92 | Directory, | ||
| 93 | } | ||
| 94 | |||
| 85 | #[derive(Debug)] | 95 | #[derive(Debug)] |
| 86 | pub struct Link { | 96 | pub struct Link { |
| 87 | id: LinkID, | 97 | id: LinkID, |
| 98 | ty: LinkType, | ||
| 88 | /// The origin path, when joined with the depot base path, must be valid and it point to a file that exists. | 99 | /// The origin path, when joined with the depot base path, must be valid and it point to a file that exists. |
| 89 | origin: PathBuf, | 100 | origin: PathBuf, |
| 90 | /// Canonical version of origin | 101 | /// Canonical version of origin |
| @@ -101,6 +112,10 @@ impl Link { | |||
| 101 | self.id | 112 | self.id |
| 102 | } | 113 | } |
| 103 | 114 | ||
| 115 | fn link_type(&self) -> LinkType { | ||
| 116 | self.ty | ||
| 117 | } | ||
| 118 | |||
| 104 | /// The relative path to the origin file. Relative from depot folder. | 119 | /// The relative path to the origin file. Relative from depot folder. |
| 105 | pub fn origin(&self) -> &Path { | 120 | pub fn origin(&self) -> &Path { |
| 106 | &self.origin | 121 | &self.origin |
| @@ -280,8 +295,26 @@ fn depot_create_link(depot: &Depot, link_desc: LinkCreateParams) -> Result<Link, | |||
| 280 | // let origin = origin_canonical; | 295 | // let origin = origin_canonical; |
| 281 | let destination = link_desc.destination; | 296 | let destination = link_desc.destination; |
| 282 | 297 | ||
| 298 | let ty = if origin.is_dir() { | ||
| 299 | for link in depot.links() { | ||
| 300 | if link.origin().starts_with(&origin) && link.origin() != origin { | ||
| 301 | return Err(LinkCreateError::DirectoryHasLinkedChildren(origin)); | ||
| 302 | } | ||
| 303 | } | ||
| 304 | LinkType::Directory | ||
| 305 | } else { | ||
| 306 | for link in depot.links() { | ||
| 307 | if origin.starts_with(link.origin()) { | ||
| 308 | assert_eq!(link.link_type(), LinkType::Directory); | ||
| 309 | return Err(LinkCreateError::FileHasLinkedParent(origin)); | ||
| 310 | } | ||
| 311 | } | ||
| 312 | LinkType::File | ||
| 313 | }; | ||
| 314 | |||
| 283 | Ok(Link { | 315 | Ok(Link { |
| 284 | id: Default::default(), | 316 | id: Default::default(), |
| 317 | ty, | ||
| 285 | origin, | 318 | origin, |
| 286 | origin_canonical, | 319 | origin_canonical, |
| 287 | destination, | 320 | destination, |
diff --git a/dotup_cli/src/commands/link.rs b/dotup_cli/src/commands/link.rs index bed3744..614c0ca 100644 --- a/dotup_cli/src/commands/link.rs +++ b/dotup_cli/src/commands/link.rs | |||
| @@ -24,7 +24,13 @@ pub fn main(config: Config, opts: Opts) -> anyhow::Result<()> { | |||
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | if let Some(destination) = destination { | 26 | if let Some(destination) = destination { |
| 27 | for path in collect_file_type(origins, FileType::File)? { | 27 | let collected_paths = if opts.directory { |
| 28 | origins.to_vec() | ||
| 29 | } else { | ||
| 30 | collect_file_type(origins, FileType::File)? | ||
| 31 | }; | ||
| 32 | |||
| 33 | for path in collected_paths { | ||
| 28 | let link_desc = LinkCreateParams { | 34 | let link_desc = LinkCreateParams { |
| 29 | origin: path, | 35 | origin: path, |
| 30 | destination: destination.clone(), | 36 | destination: destination.clone(), |
