buildkit_llb/ops/fs/
mkfile.rs1use std::collections::HashMap;
2use std::path::{Path, PathBuf};
3
4use buildkit_proto::pb;
5
6use super::path::LayerPath;
7use super::FileOperation;
8
9use crate::serialization::{Context, Result};
10use crate::utils::OutputIdx;
11
12#[derive(Debug)]
13pub struct MakeFileOperation<'a> {
14 path: LayerPath<'a, PathBuf>,
15 output: OutputIdx,
16
17 data: Option<Vec<u8>>,
18
19 description: HashMap<String, String>,
20 caps: HashMap<String, bool>,
21}
22
23impl<'a> MakeFileOperation<'a> {
24 pub(crate) fn new<P>(output: OutputIdx, path: LayerPath<'a, P>) -> Self
25 where
26 P: AsRef<Path>,
27 {
28 let mut caps = HashMap::<String, bool>::new();
29 caps.insert("file.base".into(), true);
30
31 MakeFileOperation {
32 path: path.into_owned(),
33 output,
34
35 data: None,
36
37 caps,
38 description: Default::default(),
39 }
40 }
41
42 pub fn data(mut self, bytes: Vec<u8>) -> Self {
43 self.data = Some(bytes);
44 self
45 }
46
47 pub fn into_operation(self) -> super::sequence::SequenceOperation<'a> {
48 super::sequence::SequenceOperation::new().append(self)
49 }
50}
51
52impl<'a> FileOperation for MakeFileOperation<'a> {
53 fn output(&self) -> i32 {
54 self.output.into()
55 }
56
57 fn serialize_inputs(&self, cx: &mut Context) -> Result<Vec<pb::Input>> {
58 if let LayerPath::Other(ref op, ..) = self.path {
59 let serialized_from_head = cx.register(op.operation())?;
60
61 let inputs = vec![pb::Input {
62 digest: serialized_from_head.digest.clone(),
63 index: op.output().into(),
64 }];
65
66 Ok(inputs)
67 } else {
68 Ok(Vec::with_capacity(0))
69 }
70 }
71
72 fn serialize_action(
73 &self,
74 inputs_count: usize,
75 inputs_offset: usize,
76 ) -> Result<pb::FileAction> {
77 let (src_idx, path) = match self.path {
78 LayerPath::Scratch(ref path) => (-1, path.to_string_lossy().into()),
79 LayerPath::Other(_, ref path) => (inputs_offset as i64, path.to_string_lossy().into()),
80
81 LayerPath::Own(ref output, ref path) => {
82 let output: i64 = output.into();
83
84 (inputs_count as i64 + output, path.to_string_lossy().into())
85 }
86 };
87
88 Ok(pb::FileAction {
89 input: src_idx,
90 secondary_input: -1,
91
92 output: i64::from(self.output()),
93
94 action: Some(pb::file_action::Action::Mkfile(pb::FileActionMkFile {
95 path,
96
97 data: self.data.clone().unwrap_or_else(|| Vec::with_capacity(0)),
98
99 mode: -1,
101
102 timestamp: -1,
104
105 owner: None,
107 })),
108 })
109 }
110}