Skip to content

Commit

Permalink
add more rebag options and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pwinckles committed Feb 22, 2022
1 parent ad83670 commit f896d08
Show file tree
Hide file tree
Showing 45 changed files with 237 additions and 46 deletions.
59 changes: 50 additions & 9 deletions src/bagit/bag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub struct Bag {
pub struct BagUpdater {
bag: Bag,
recalculate_payload_manifests: bool,
algorithms: Vec<DigestAlgorithm>,
bagging_date: Option<String>,
software_agent: Option<String>,
}

#[derive(Debug)]
Expand Down Expand Up @@ -182,7 +185,14 @@ impl Bag {
}
}

// TODO get tags
pub fn declaration(&self) -> &BagDeclaration {
&self.declaration
}

pub fn bag_info(&self) -> &BagInfo {
&self.bag_info
}

// TODO get fetch entries
// TODO download fetch entries

Expand All @@ -197,12 +207,37 @@ impl BagUpdater {
Self {
bag,
recalculate_payload_manifests: true,
algorithms: Vec::new(),
bagging_date: None,
software_agent: None,
}
}

// TODO add algorithm
// TODO modify tags
// TODO add fetch item
/// Adds a digest algorithm to use for calculating manifests
pub fn with_algorithm(mut self, algorithm: DigestAlgorithm) -> Self {
self.algorithms.push(algorithm);
self
}

/// Sets the algorithms to use when calculating manifests. An empty slice will result in
/// the algorithms that were used to calculate the existing manifests to be used.
pub fn with_algorithms(mut self, algorithms: &[DigestAlgorithm]) -> Self {
self.algorithms.clear();
self.algorithms.extend_from_slice(algorithms);
self
}

/// Sets the Bagging-Date to add to bag-info.txt. None for the default value.
pub fn with_bagging_date(mut self, bagging_date: Option<String>) -> Self {
self.bagging_date = bagging_date;
self
}

/// Sets the Bag-Software-Agent to add to bag-info.txt. None for the default value.
pub fn with_software_agent(mut self, software_agent: Option<String>) -> Self {
self.software_agent = software_agent;
self
}

/// Enables/disables payload manifest recalculation on `finalize()`. This is enabled by default,
/// but can be disabled if the digest algorithms in use have not changed and there were no
Expand All @@ -215,14 +250,20 @@ impl BagUpdater {
/// Writes the changes to disk and recalculates manifests.
pub fn finalize(mut self) -> Result<Bag> {
let base_dir = &self.bag.base_dir;
let algorithms = &self.bag.algorithms;
let algorithms = if self.algorithms.is_empty() {
&self.bag.algorithms
} else {
self.algorithms.sort();
self.algorithms.dedup();
&self.algorithms
};

// TODO should updating these values keep the original position?
// TODO need an option of overriding this
self.bag.bag_info.add_bagging_date(current_date_str())?;
self.bag
.bag_info
.add_software_agent(bagr_software_agent())?;
.add_bagging_date(self.bagging_date.unwrap_or_else(current_date_str))?;
self.bag
.bag_info
.add_software_agent(self.software_agent.unwrap_or_else(bagr_software_agent))?;

if self.recalculate_payload_manifests {
delete_payload_manifests(base_dir)?;
Expand Down
108 changes: 71 additions & 37 deletions src/bin/bagr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,33 @@ pub struct RebagCmd {
/// By default, this is the current directory.
#[clap(short, long, value_name = "BAG_PATH")]
pub bag_path: Option<PathBuf>,

/// Digest algorithms to use when creating manifest files.
///
/// By default, the same algorithms are used as were used to compute the existing manifests.
/// If algorithms are specified here, then only the specified algorithms will be used, and
/// the algorithms used by the existing manifests will be ignored.
#[clap(
arg_enum,
short = 'a',
long,
value_name = "ALGORITHM",
ignore_case = true,
multiple_occurrences = true
)]
pub digest_algorithm: Vec<DigestAlgorithm>,

/// Value of the Bagging-Date tag in bag-info.txt
///
/// Defaults to the current date. Should be in YYYY-MM-DD format.
#[clap(long, value_name = "YYYY-MM-DD")]
pub bagging_date: Option<String>,

/// Value of the Bag-Software-Agent tag in bag-info.txt
///
/// Defaults to this bagr version
#[clap(long, value_name = "AGENT")]
pub software_agent: Option<String>,
}

#[derive(ArgEnum, Debug, Clone, Copy)]
Expand Down Expand Up @@ -195,97 +222,104 @@ fn main() {
args.no_styles = true;
}

// TODO
match args.command {
Command::Bag(sub_args) => {
if let Err(e) = bag_cmd(sub_args) {
Command::Bag(cmd) => {
if let Err(e) = exec_bag(cmd) {
error!("Failed to create bag: {}", e);
exit(1);
}
}
Command::Rebag(sub_args) => match open_bag(defaulted_path(sub_args.bag_path)) {
Ok(bag) => {
info!("Opened bag: {:?}", bag);

if let Err(e) = bag.update().finalize() {
error!("Failed to rebag: {}", e);
exit(1);
}
}
Err(e) => {
Command::Rebag(cmd) => {
if let Err(e) = exec_rebag(cmd) {
error!("Failed to rebag: {}", e);
exit(1);
}
},
}
}
}

fn bag_cmd(sub_args: BagCmd) -> Result<Bag> {
fn exec_bag(cmd: BagCmd) -> Result<Bag> {
let mut bag_info = BagInfo::new();

if let Some(date) = sub_args.bagging_date {
if let Some(date) = cmd.bagging_date {
bag_info.add_bagging_date(date)?;
}
if let Some(agent) = sub_args.software_agent {
if let Some(agent) = cmd.software_agent {
bag_info.add_software_agent(agent)?;
}
if let Some(group_id) = sub_args.bag_group_identifier {
if let Some(group_id) = cmd.bag_group_identifier {
bag_info.add_bag_group_identifier(group_id)?;
}
if let Some(count) = sub_args.bag_count {
if let Some(count) = cmd.bag_count {
bag_info.add_bag_count(count)?;
}
if let Some(size) = sub_args.bag_size {
if let Some(size) = cmd.bag_size {
bag_info.add_bag_size(size)?;
}

for org in sub_args.source_organization {
for org in cmd.source_organization {
bag_info.add_source_organization(org)?;
}
for address in sub_args.organization_address {
for address in cmd.organization_address {
bag_info.add_organization_address(address)?;
}
for name in sub_args.contact_name {
for name in cmd.contact_name {
bag_info.add_contact_name(name)?;
}
for phone in sub_args.contact_phone {
for phone in cmd.contact_phone {
bag_info.add_contact_phone(phone)?;
}
for email in sub_args.contact_email {
for email in cmd.contact_email {
bag_info.add_contact_email(email)?;
}
for desc in sub_args.external_description {
for desc in cmd.external_description {
bag_info.add_external_description(desc)?;
}
for id in sub_args.external_identifier {
for id in cmd.external_identifier {
bag_info.add_external_identifier(id)?;
}
for desc in sub_args.internal_sender_description {
for desc in cmd.internal_sender_description {
bag_info.add_internal_sender_description(desc)?;
}
for id in sub_args.internal_sender_identifier {
for id in cmd.internal_sender_identifier {
bag_info.add_internal_sender_identifier(id)?;
}

for tag in sub_args.tag {
for tag in cmd.tag {
let split = tag.split_once(':').ok_or_else(|| InvalidTagLine {
details: format!("Label and value must be separated by a ':'. Found: {}", tag),
})?;
bag_info.add_tag(split.0.trim(), split.1.trim())?;
}

create_bag(
defaulted_path(sub_args.source),
defaulted_path(sub_args.destination),
defaulted_path(cmd.source),
defaulted_path(cmd.destination),
bag_info,
&sub_args
.digest_algorithm
.into_iter()
.map(|e| e.into())
.collect::<Vec<BagItDigestAlgorithm>>(),
&map_algorithms(&cmd.digest_algorithm),
)
}

fn exec_rebag(cmd: RebagCmd) -> Result<Bag> {
let bag = open_bag(defaulted_path(cmd.bag_path))?;
info!("Opened bag: {:?}", bag);

// TODO add option for not recalculating payload manifests

bag.update()
.with_bagging_date(cmd.bagging_date)
.with_software_agent(cmd.software_agent)
.with_algorithms(&map_algorithms(&cmd.digest_algorithm))
.finalize()
}

fn defaulted_path(path: Option<PathBuf>) -> PathBuf {
path.unwrap_or_else(|| PathBuf::from("."))
}

fn map_algorithms(algorithms: &[DigestAlgorithm]) -> Vec<BagItDigestAlgorithm> {
algorithms
.iter()
.map(|e| (*e).into())
.collect::<Vec<BagItDigestAlgorithm>>()
}
5 changes: 5 additions & 0 deletions tests/cli_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
fn bag_cli_tests() {
trycmd::TestCases::new().case("tests/cmd/bag/*.toml");
}

#[test]
fn rebag_cli_tests() {
trycmd::TestCases::new().case("tests/cmd/rebag/*.toml");
}
4 changes: 4 additions & 0 deletions tests/cmd/rebag/all-the-options.out/bag-info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Custom-Tag: some value
Bagging-Date: 2022-02-17
Bag-Software-Agent: different-agent
Payload-Oxum: 32.3
2 changes: 2 additions & 0 deletions tests/cmd/rebag/all-the-options.out/bagit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BagIt-Version: 1.0
Tag-File-Character-Encoding: UTF-8
1 change: 1 addition & 0 deletions tests/cmd/rebag/all-the-options.out/data/dir/file2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file 2
1 change: 1 addition & 0 deletions tests/cmd/rebag/all-the-options.out/data/dir2/file3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
new file
2 changes: 2 additions & 0 deletions tests/cmd/rebag/all-the-options.out/data/file1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file 1
updated!
3 changes: 3 additions & 0 deletions tests/cmd/rebag/all-the-options.out/manifest-md5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
4349cfeff8e2eb74dffc369bb5fd084e data/dir/file2.txt
18519bfbd592b4e6cb238c5ccdbc209f data/dir2/file3.txt
33ef2dc68bf2a81c18b7ed096ebc36ae data/file1.txt
3 changes: 3 additions & 0 deletions tests/cmd/rebag/all-the-options.out/manifest-sha256.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0b7e1391e807365614c548fd10a4a543cf0654268529f3fe768ed7042624c006 data/dir/file2.txt
0f15384d18789b1ebf3043dc7b6bc27273c8576373fbeb6f3e15854b588141c0 data/dir2/file3.txt
50852cd90422339e4b8d6b24857e29082793d7a4928151b1f9f4b5480486a60f data/file1.txt
4 changes: 4 additions & 0 deletions tests/cmd/rebag/all-the-options.out/tagmanifest-md5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
085345c69ab2c8810c1521241e7c517b bag-info.txt
eaa2c609ff6371712f623f5531945b44 bagit.txt
c040e49921880a7e0ec3c755abba8873 manifest-md5.txt
a3fd2cd9ab0c0be10d96b529bb5d01d0 manifest-sha256.txt
4 changes: 4 additions & 0 deletions tests/cmd/rebag/all-the-options.out/tagmanifest-sha256.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
536e8a1d996b90f4604a3ee15e72e4f81c3b1ea4400421103f38dbe178b46619 bag-info.txt
1712ecfb074bf29c4188ad3421032509159a09739fd604f8fe57038b4ddefcc9 bagit.txt
0eade43a3568aa249d913b81fb74e50e6b811253c8bc9f0bc6996e5bba043307 manifest-md5.txt
98b4965b4b230864f94e98758a10f8c3e498b24d5d3704195581f73b06c4537c manifest-sha256.txt
10 changes: 10 additions & 0 deletions tests/cmd/rebag/all-the-options.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fs.sandbox = true
fs.base = "basic-rebag.in"

bin.name = "bagr"
args = """
rebag \
--bagging-date 2022-02-17 \
--software-agent different-agent \
--digest-algorithm md5 \
--digest-algorithm sha256"""
4 changes: 4 additions & 0 deletions tests/cmd/rebag/basic-rebag.in/bag-info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bagging-Date: 2022-02-16
Bag-Software-Agent: bagr v0.1.0 <https://github.com/pwinckles/bagr>
Payload-Oxum: 14.2
Custom-Tag: some value
2 changes: 2 additions & 0 deletions tests/cmd/rebag/basic-rebag.in/bagit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BagIt-Version: 1.0
Tag-File-Character-Encoding: UTF-8
1 change: 1 addition & 0 deletions tests/cmd/rebag/basic-rebag.in/data/dir/file2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file 2
1 change: 1 addition & 0 deletions tests/cmd/rebag/basic-rebag.in/data/dir2/file3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
new file
2 changes: 2 additions & 0 deletions tests/cmd/rebag/basic-rebag.in/data/file1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file 1
updated!
2 changes: 2 additions & 0 deletions tests/cmd/rebag/basic-rebag.in/manifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
7bfbc95b531e0ebadb5bcf9a82df161bb6b75b8ab7cc44b4b2e8aa461c8e716aea0fa802eb447e80e09cc066d4908e1c37bcbf2e7ceed0738bfe1c92e053d4fd data/dir/file2.txt
c781abe810e6ac01e946aef70bccee87aa4fddb54b0c8260a3572845fe15cac454f259459c60ac1822405efaef3d00a4a71191bc1a29420f94ed32cdddeb12fe data/file1.txt
3 changes: 3 additions & 0 deletions tests/cmd/rebag/basic-rebag.in/tagmanifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
226c565aea1e609eef0fcc8524104b5c73ea00d49e0fb72654181aa68f9019a4da490d2a5bdf7a3bab9e541a002ad817a96d212195de4b0a423b71a2831d68a3 bag-info.txt
1d73ae108d4109b61f56698a5e19ee1f8947bdf8940bbce6adbe5e0940c2363caace6a547b4f1b3ec6a4fd2b7fa845e9cb9d28823bc72c59971718bb26f2fbd8 bagit.txt
49ed4e071201e8a98e4a01497496916259fffe296e85a6a0d422934c5021a3ff2482feb77d0a4d948a4ddd5204c7f83c4c7b6416c9a90d649185388e2430f8fb manifest-sha512.txt
4 changes: 4 additions & 0 deletions tests/cmd/rebag/basic-rebag.out/bag-info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Custom-Tag: some value
Bagging-Date: 2022-02-17
Bag-Software-Agent: bagr v0.1.0 <https://github.com/pwinckles/bagr>
Payload-Oxum: 32.3
2 changes: 2 additions & 0 deletions tests/cmd/rebag/basic-rebag.out/bagit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BagIt-Version: 1.0
Tag-File-Character-Encoding: UTF-8
1 change: 1 addition & 0 deletions tests/cmd/rebag/basic-rebag.out/data/dir/file2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file 2
1 change: 1 addition & 0 deletions tests/cmd/rebag/basic-rebag.out/data/dir2/file3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
new file
2 changes: 2 additions & 0 deletions tests/cmd/rebag/basic-rebag.out/data/file1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file 1
updated!
3 changes: 3 additions & 0 deletions tests/cmd/rebag/basic-rebag.out/manifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
7bfbc95b531e0ebadb5bcf9a82df161bb6b75b8ab7cc44b4b2e8aa461c8e716aea0fa802eb447e80e09cc066d4908e1c37bcbf2e7ceed0738bfe1c92e053d4fd data/dir/file2.txt
23f43827fb81533daff688aa983b7908d19616cc4e1fc2689fed287dcfd5117149e829a284036b3e4eae27fa476f041ea4f99af771cf6fa169ab56dec200a41f data/dir2/file3.txt
eb78643b4f0fff06eecb19a51318ed9a7fa3d5e36be2158a087a84bc1cf92f77b110706e1dd079e58702a961bde6125390183fea258ec384cabacbef1c245fb4 data/file1.txt
3 changes: 3 additions & 0 deletions tests/cmd/rebag/basic-rebag.out/tagmanifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
9ef93d22c70b1291e1aa1bf5d032591e6435dd9f76976675b857463d32119ef571213f2abd17536c9472ee2ff000cfe1aace1b8d963f7006c7af631d149d3896 bag-info.txt
1d73ae108d4109b61f56698a5e19ee1f8947bdf8940bbce6adbe5e0940c2363caace6a547b4f1b3ec6a4fd2b7fa845e9cb9d28823bc72c59971718bb26f2fbd8 bagit.txt
222233b1fae28d5b4ec8affc4603888583a78e4c1efeda057837acdb2c4f1660197443859dd217fcea89f26088abc6b8da9ea99f518abce30a7b898750b069af manifest-sha512.txt
5 changes: 5 additions & 0 deletions tests/cmd/rebag/basic-rebag.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fs.sandbox = true
fs.base = "basic-rebag.in"

bin.name = "bagr"
args = "rebag --bagging-date 2022-02-17"
4 changes: 4 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/bag-info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Bagging-Date: 2022-02-16
Bag-Software-Agent: bagr v0.1.0 <https://github.com/pwinckles/bagr>
Payload-Oxum: 14.2
Custom-Tag: some value
2 changes: 2 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/bagit.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BagIt-Version: 1.0
Tag-File-Character-Encoding: UTF-8
2 changes: 2 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/custom-tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
custom: file
super: special
1 change: 1 addition & 0 deletions tests/cmd/rebag/new-tag-files.in/data/dir/file2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file 2
1 change: 1 addition & 0 deletions tests/cmd/rebag/new-tag-files.in/data/dir2/file3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
new file
2 changes: 2 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/data/file1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
file 1
updated!
2 changes: 2 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/manifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
7bfbc95b531e0ebadb5bcf9a82df161bb6b75b8ab7cc44b4b2e8aa461c8e716aea0fa802eb447e80e09cc066d4908e1c37bcbf2e7ceed0738bfe1c92e053d4fd data/dir/file2.txt
c781abe810e6ac01e946aef70bccee87aa4fddb54b0c8260a3572845fe15cac454f259459c60ac1822405efaef3d00a4a71191bc1a29420f94ed32cdddeb12fe data/file1.txt
3 changes: 3 additions & 0 deletions tests/cmd/rebag/new-tag-files.in/tagmanifest-sha512.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
226c565aea1e609eef0fcc8524104b5c73ea00d49e0fb72654181aa68f9019a4da490d2a5bdf7a3bab9e541a002ad817a96d212195de4b0a423b71a2831d68a3 bag-info.txt
1d73ae108d4109b61f56698a5e19ee1f8947bdf8940bbce6adbe5e0940c2363caace6a547b4f1b3ec6a4fd2b7fa845e9cb9d28823bc72c59971718bb26f2fbd8 bagit.txt
49ed4e071201e8a98e4a01497496916259fffe296e85a6a0d422934c5021a3ff2482feb77d0a4d948a4ddd5204c7f83c4c7b6416c9a90d649185388e2430f8fb manifest-sha512.txt
Loading

0 comments on commit f896d08

Please sign in to comment.