A library for writing host-specific, single-binary configuration management and deployment tools
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
1.8 KiB

7 years ago
7 years ago
7 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
7 years ago
5 years ago
6 years ago
  1. use std::error::Error;
  2. use std::fmt;
  3. use std::fs;
  4. use std::io;
  5. use std::path::Path;
  6. use resources::Resource;
  7. use symbols::{Action, OwnedSymbolAction, Symbol, SymbolAction, SymbolRunner};
  8. pub struct Dir<D>
  9. where
  10. D: AsRef<str>,
  11. {
  12. path: D,
  13. }
  14. impl<D> Dir<D>
  15. where
  16. D: AsRef<str>,
  17. {
  18. pub fn new(path: D) -> Self {
  19. Dir { path }
  20. }
  21. }
  22. impl<D> Symbol for Dir<D>
  23. where
  24. D: AsRef<str>,
  25. {
  26. fn target_reached(&self) -> Result<bool, Box<dyn Error>> {
  27. let metadata = fs::metadata(self.path.as_ref());
  28. // Check if dir exists
  29. if let Err(e) = metadata {
  30. return if e.kind() == io::ErrorKind::NotFound {
  31. Ok(false)
  32. } else {
  33. Err(Box::new(e))
  34. };
  35. }
  36. if metadata.unwrap().is_dir() {
  37. Ok(true)
  38. } else {
  39. Err(Box::new(io::Error::new(
  40. io::ErrorKind::AlreadyExists,
  41. "Could not create a directory, non-directory file exists",
  42. )))
  43. }
  44. }
  45. fn execute(&self) -> Result<(), Box<dyn Error>> {
  46. fs::create_dir(self.path.as_ref()).map_err(|e| Box::new(e) as Box<dyn Error>)
  47. }
  48. fn get_prerequisites(&self) -> Vec<Resource> {
  49. if let Some(parent) = Path::new(self.path.as_ref()).parent() {
  50. vec![Resource::new("dir", parent.to_string_lossy())]
  51. } else {
  52. vec![]
  53. }
  54. }
  55. fn provides(&self) -> Option<Vec<Resource>> {
  56. Some(vec![Resource::new("dir", self.path.as_ref())])
  57. }
  58. fn as_action<'a>(&'a self, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a> {
  59. Box::new(SymbolAction::new(runner, self))
  60. }
  61. fn into_action<'a>(self: Box<Self>, runner: &'a dyn SymbolRunner) -> Box<dyn Action + 'a>
  62. where
  63. Self: 'a,
  64. {
  65. Box::new(OwnedSymbolAction::new(runner, *self))
  66. }
  67. }
  68. impl<D> fmt::Display for Dir<D>
  69. where
  70. D: AsRef<str>,
  71. {
  72. fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
  73. write!(f, "Dir {}", self.path.as_ref())
  74. }
  75. }