aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-06-09 00:00:12 +0900
committernsfisis <nsfisis@gmail.com>2026-06-09 00:00:49 +0900
commit1c0eb589741de4aa52ef941ff9315b34dbe48aa0 (patch)
tree8d821cf3a7fb3f8c753dec7861ad9597f6948493 /crates
parente5b789616ec4c1cbd152c5ccbefe2d27ced4a18f (diff)
downloadphp-shirabe-1c0eb589741de4aa52ef941ff9315b34dbe48aa0.tar.gz
php-shirabe-1c0eb589741de4aa52ef941ff9315b34dbe48aa0.tar.zst
php-shirabe-1c0eb589741de4aa52ef941ff9315b34dbe48aa0.zip
feat(datetime): resolve datetime TODOs
Introduce shim functions and constants, replacing the ad-hoc chrono format strings and parse helpers used as phase-b placeholders. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-php-shim/Cargo.toml1
-rw-r--r--crates/shirabe-php-shim/src/lib.rs24
-rw-r--r--crates/shirabe/src/advisory/auditor.rs19
-rw-r--r--crates/shirabe/src/advisory/partial_security_advisory.rs13
-rw-r--r--crates/shirabe/src/advisory/security_advisory.rs4
-rw-r--r--crates/shirabe/src/cache.rs22
-rw-r--r--crates/shirabe/src/command/show_command.rs31
-rw-r--r--crates/shirabe/src/compiler.rs18
-rw-r--r--crates/shirabe/src/package/dumper/array_dumper.rs4
-rw-r--r--crates/shirabe/src/package/loader/array_loader.rs15
-rw-r--r--crates/shirabe/src/package/loader/validating_array_loader.rs28
-rw-r--r--crates/shirabe/src/package/locker.rs1
-rw-r--r--crates/shirabe/src/repository/vcs/forgejo_driver.rs9
-rw-r--r--crates/shirabe/src/repository/vcs/fossil_driver.rs20
-rw-r--r--crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs20
-rw-r--r--crates/shirabe/src/repository/vcs/git_driver.rs16
-rw-r--r--crates/shirabe/src/repository/vcs/github_driver.rs23
-rw-r--r--crates/shirabe/src/repository/vcs/gitlab_driver.rs22
-rw-r--r--crates/shirabe/src/repository/vcs/hg_driver.rs18
-rw-r--r--crates/shirabe/src/repository/vcs/perforce_driver.rs4
-rw-r--r--crates/shirabe/src/repository/vcs/svn_driver.rs16
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver.rs13
-rw-r--r--crates/shirabe/src/repository/vcs/vcs_driver_interface.rs7
23 files changed, 189 insertions, 159 deletions
diff --git a/crates/shirabe-php-shim/Cargo.toml b/crates/shirabe-php-shim/Cargo.toml
index 30e132f..b2a2077 100644
--- a/crates/shirabe-php-shim/Cargo.toml
+++ b/crates/shirabe-php-shim/Cargo.toml
@@ -5,6 +5,7 @@ edition.workspace = true
[dependencies]
anyhow.workspace = true
+chrono.workspace = true
indexmap.workspace = true
serde.workspace = true
zip.workspace = true
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs
index 835e1c1..433b8db 100644
--- a/crates/shirabe-php-shim/src/lib.rs
+++ b/crates/shirabe-php-shim/src/lib.rs
@@ -1740,8 +1740,6 @@ pub fn abs(_value: i64) -> i64 {
todo!()
}
-pub const DATE_ATOM: &str = "Y-m-d\\TH:i:sP";
-
pub fn ucfirst(_s: &str) -> String {
todo!()
}
@@ -2409,7 +2407,6 @@ pub const OPENSSL_VERSION_NUMBER: i64 = 0;
pub const OPENSSL_VERSION_TEXT: &str = "";
pub const PHP_BINARY: &str = "";
pub const PHP_WINDOWS_VERSION_BUILD: i64 = 0;
-pub const DATE_RFC3339: &str = "Y-m-d\\TH:i:sP";
pub const PREG_BACKTRACK_LIMIT_ERROR: i64 = 2;
#[derive(Debug, Clone)]
@@ -2459,3 +2456,24 @@ pub fn zlib_decode(_data: &str) -> Option<String> {
pub const STREAM_NOTIFY_FAILURE: i64 = 9;
pub const STREAM_NOTIFY_FILE_SIZE_IS: i64 = 5;
pub const STREAM_NOTIFY_PROGRESS: i64 = 7;
+
+pub fn date_create<Tz: chrono::TimeZone>(s: &str) -> chrono::ParseResult<chrono::DateTime<Tz>> {
+ todo!()
+}
+
+/// PHP: \DATE_RFC3339 ("Y-m-d\TH:i:sP").
+pub const DATE_RFC3339: &str = "%Y-%m-%dT%H:%M:%S%:z";
+
+/// PHP: \DATE_ATOM (equivalent to \DATE_RFC3339).
+pub const DATE_ATOM: &str = DATE_RFC3339;
+
+/// Convert PHP-compatible date time format to strftime-compatible format.
+/// Only the patterns Composer actually passes are supported; anything else panics.
+pub fn date_format_to_strftime(format: &str) -> &'static str {
+ match format {
+ "Y-m-d H:i:s" => "%Y-%m-%d %H:%M:%S",
+ "Y-m-d" => "%Y-%m-%d",
+ "Ymd" => "%Y%m%d",
+ other => panic!("Unsupported PHP date format: {other:?}"),
+ }
+}
diff --git a/crates/shirabe/src/advisory/auditor.rs b/crates/shirabe/src/advisory/auditor.rs
index 179278a..2b71237 100644
--- a/crates/shirabe/src/advisory/auditor.rs
+++ b/crates/shirabe/src/advisory/auditor.rs
@@ -6,8 +6,8 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_external_packages::symfony::console::formatter::OutputFormatter;
use shirabe_php_shim::{
- InvalidArgumentException, PhpMixed, array_all, array_any, array_key_exists, array_keys,
- array_reduce, get_class, sprintf, str_starts_with,
+ DATE_ATOM, InvalidArgumentException, PhpMixed, array_all, array_any, array_key_exists,
+ array_keys, array_reduce, get_class, sprintf, str_starts_with,
};
use crate::advisory::AnySecurityAdvisory;
@@ -464,11 +464,7 @@ impl Auditor {
sa.title.clone(),
self.get_url(sa),
sa.affected_versions().get_pretty_string(),
- // TODO(phase-b): PHP uses `$advisory->reportedAt->format(DATE_ATOM)`, but
- // shim DATE_ATOM ("Y-m-d\TH:i:sP") is a PHP format string incompatible with
- // chrono. Using the chrono equivalent directly; revisit once a PHP-style date
- // formatter exists (see also locker.rs DATE_RFC3339).
- sa.reported_at.format("%Y-%m-%dT%H:%M:%S%:z").to_string(),
+ sa.reported_at.format(DATE_ATOM).to_string(),
];
if let Some(ignored) = advisory.as_ignored() {
headers.push("Ignore reason".to_string());
@@ -523,14 +519,7 @@ impl Auditor {
"Affected versions: {}",
OutputFormatter::escape(&sa.affected_versions().get_pretty_string())
));
- error.push(format!(
- "Reported at: {}",
- // TODO(phase-b): PHP uses `$advisory->reportedAt->format(DATE_ATOM)`, but
- // shim DATE_ATOM ("Y-m-d\TH:i:sP") is a PHP format string incompatible with
- // chrono. Using the chrono equivalent directly; revisit once a PHP-style date
- // formatter exists (see also locker.rs DATE_RFC3339).
- sa.reported_at.format("%Y-%m-%dT%H:%M:%S%:z")
- ));
+ error.push(format!("Reported at: {}", sa.reported_at.format(DATE_ATOM)));
if let Some(ignored) = advisory.as_ignored() {
error.push(format!(
"Ignore reason: {}",
diff --git a/crates/shirabe/src/advisory/partial_security_advisory.rs b/crates/shirabe/src/advisory/partial_security_advisory.rs
index 2062570..f72ecaa 100644
--- a/crates/shirabe/src/advisory/partial_security_advisory.rs
+++ b/crates/shirabe/src/advisory/partial_security_advisory.rs
@@ -4,10 +4,10 @@ use crate::advisory::AnySecurityAdvisory;
use crate::advisory::SecurityAdvisory;
use crate::package::version::VersionParser;
use anyhow::Result;
-use chrono::{DateTime, TimeZone, Utc};
+use chrono::{DateTime, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_php_shim::{PhpMixed, UnexpectedValueException};
+use shirabe_php_shim::{DATE_RFC3339, PhpMixed, UnexpectedValueException};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::SimpleConstraint;
@@ -57,12 +57,9 @@ impl PartialSecurityAdvisory {
&& data.contains_key("reportedAt");
if has_full_data {
- let reported_at: DateTime<Utc> = Utc
- .datetime_from_str(
- data["reportedAt"].as_string().unwrap_or(""),
- "%Y-%m-%dT%H:%M:%S+00:00",
- )
- .unwrap_or_default();
+ let reported_at: DateTime<Utc> =
+ shirabe_php_shim::date_create(data["reportedAt"].as_string().unwrap_or(""))
+ .unwrap_or_default();
let sources: Vec<IndexMap<String, String>> = data["sources"]
.as_list()
.map(|list| {
diff --git a/crates/shirabe/src/advisory/security_advisory.rs b/crates/shirabe/src/advisory/security_advisory.rs
index 2c5a309..7c258ee 100644
--- a/crates/shirabe/src/advisory/security_advisory.rs
+++ b/crates/shirabe/src/advisory/security_advisory.rs
@@ -2,17 +2,17 @@
use chrono::{DateTime, Utc};
use indexmap::IndexMap;
+use shirabe_php_shim::DATE_RFC3339;
use shirabe_semver::constraint::AnyConstraint;
use crate::advisory::IgnoredSecurityAdvisory;
use crate::advisory::PartialSecurityAdvisory;
-/// Matches PHP's `format(DATE_RFC3339)`, e.g. "2020-01-01T00:00:00+00:00".
fn serialize_date_rfc3339<S: serde::Serializer>(
dt: &DateTime<Utc>,
serializer: S,
) -> Result<S::Ok, S::Error> {
- serializer.serialize_str(&dt.format("%Y-%m-%dT%H:%M:%S%:z").to_string())
+ serializer.serialize_str(&dt.format(DATE_RFC3339).to_string())
}
#[derive(Debug, Clone, serde::Serialize)]
diff --git a/crates/shirabe/src/cache.rs b/crates/shirabe/src/cache.rs
index 1a1f67f..74e3c15 100644
--- a/crates/shirabe/src/cache.rs
+++ b/crates/shirabe/src/cache.rs
@@ -7,8 +7,9 @@ use chrono::Utc;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_external_packages::symfony::finder::Finder;
use shirabe_php_shim::{
- abs, bin2hex, dirname, file_exists, file_get_contents, file_put_contents, filemtime, hash_file,
- is_dir, is_writable, mkdir, random_bytes, random_int, rename, time, unlink,
+ abs, bin2hex, date_format_to_strftime, dirname, file_exists, file_get_contents,
+ file_put_contents, filemtime, hash_file, is_dir, is_writable, mkdir, random_bytes, random_int,
+ rename, time, unlink,
};
use crate::io::IOInterface;
@@ -278,12 +279,13 @@ impl Cache {
pub fn gc(&mut self, ttl: i64, max_size: i64) -> bool {
if self.is_enabled() && !self.read_only {
- let mut expire = Utc::now();
- // PHP: $expire->modify('-'.$ttl.' seconds');
- expire -= chrono::Duration::seconds(ttl);
+ let expire = Utc::now() - chrono::Duration::seconds(ttl);
let mut finder = self.get_finder();
- finder.date(&format!("until {}", expire.format("%Y-%m-%d %H:%M:%S")));
+ finder.date(&format!(
+ "until {}",
+ expire.format(date_format_to_strftime("Y-m-d H:i:s"))
+ ));
for file in &mut finder {
let _ = self.filesystem.borrow_mut().unlink(&file.get_pathname());
}
@@ -309,15 +311,17 @@ impl Cache {
pub fn gc_vcs_cache(&mut self, ttl: i64) -> bool {
if self.is_enabled() {
- let mut expire = Utc::now();
- expire -= chrono::Duration::seconds(ttl);
+ let expire = Utc::now() - chrono::Duration::seconds(ttl);
let mut finder = Finder::create();
finder
.r#in(&self.root)
.directories()
.depth(0)
- .date(&format!("until {}", expire.format("%Y-%m-%d %H:%M:%S")));
+ .date(&format!(
+ "until {}",
+ expire.format(date_format_to_strftime("Y-m-d H:i:s"))
+ ));
for file in &mut finder {
let _ = self
.filesystem
diff --git a/crates/shirabe/src/command/show_command.rs b/crates/shirabe/src/command/show_command.rs
index e99005e..7ee103a 100644
--- a/crates/shirabe/src/command/show_command.rs
+++ b/crates/shirabe/src/command/show_command.rs
@@ -9,8 +9,9 @@ use shirabe_external_packages::symfony::console::formatter::OutputFormatterStyle
use shirabe_external_packages::symfony::console::input::InputInterface;
use shirabe_external_packages::symfony::console::output::OutputInterface;
use shirabe_php_shim::{
- InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException, array_search,
- date, extension_loaded, in_array, realpath, strtolower, version_compare,
+ DATE_ATOM, InvalidArgumentException, LogicException, PhpMixed, UnexpectedValueException,
+ array_search, date, date_format_to_strftime, extension_loaded, in_array, realpath, strtolower,
+ version_compare,
};
use shirabe_semver::constraint::AnyConstraint;
@@ -1026,7 +1027,7 @@ impl ShowCommand {
.insert("release-age".to_string(), PhpMixed::String(age));
package_view_data.insert(
"release-date".to_string(),
- PhpMixed::String(release_date.to_rfc3339()),
+ PhpMixed::String(release_date.format(DATE_ATOM).to_string()),
);
} else {
package_view_data.insert(
@@ -1062,7 +1063,7 @@ impl ShowCommand {
if let Some(rd) = latest.get_release_date() {
package_view_data.insert(
"latest-release-date".to_string(),
- PhpMixed::String(rd.to_rfc3339()),
+ PhpMixed::String(rd.format(DATE_ATOM).to_string()),
);
} else {
package_view_data.insert(
@@ -1666,7 +1667,7 @@ impl ShowCommand {
let rel = self.get_relative_time(&rd);
self.get_io().write(&format!(
"<info>released</info> : {}, {}",
- rd.format("%Y-%m-%d"),
+ rd.format(date_format_to_strftime("Y-m-d")),
rel
));
}
@@ -1677,7 +1678,11 @@ impl ShowCommand {
None => String::new(),
Some(rd) => {
let rel = self.get_relative_time(&rd);
- format!(" released {}, {}", rd.format("%Y-%m-%d"), rel)
+ format!(
+ " released {}, {}",
+ rd.format(date_format_to_strftime("Y-m-d")),
+ rel
+ )
}
};
self.get_io().write(&format!(
@@ -2017,7 +2022,10 @@ impl ShowCommand {
}
if let Some(rd) = package.get_release_date() {
- json.insert("released".to_string(), PhpMixed::String(rd.to_rfc3339()));
+ json.insert(
+ "released".to_string(),
+ PhpMixed::String(rd.format(DATE_ATOM).to_string()),
+ );
}
}
@@ -2786,12 +2794,15 @@ impl ShowCommand {
}
fn get_relative_time(&self, release_date: &chrono::DateTime<chrono::Utc>) -> String {
- if release_date.format("%Y%m%d").to_string() == date("Ymd", None) {
+ if release_date
+ .format(date_format_to_strftime("Ymd"))
+ .to_string()
+ == date("Ymd", None)
+ {
return "today".to_string();
}
- let now: chrono::DateTime<chrono::Utc> = chrono::Utc::now();
- let diff = now.signed_duration_since(*release_date);
+ let diff = chrono::Utc::now().signed_duration_since(*release_date);
let days = diff.num_days();
if days < 7 {
return "this week".to_string();
diff --git a/crates/shirabe/src/compiler.rs b/crates/shirabe/src/compiler.rs
index 1088477..05177d6 100644
--- a/crates/shirabe/src/compiler.rs
+++ b/crates/shirabe/src/compiler.rs
@@ -9,8 +9,8 @@ use shirabe_external_packages::symfony::finder::Finder;
use shirabe_external_packages::symfony::finder::SplFileInfo;
use shirabe_php_shim::{
Phar, PhpMixed, RuntimeException, T_COMMENT, T_DOC_COMMENT, T_WHITESPACE,
- UnexpectedValueException, array_search, file_exists, file_get_contents, strcmp, strtr,
- strtr_array, token_get_all,
+ UnexpectedValueException, array_search, date_format_to_strftime, file_exists,
+ file_get_contents, strcmp, strtr, strtr_array, token_get_all,
};
use crate::json::JsonFile;
@@ -95,8 +95,7 @@ impl Compiler {
let version_date_str = Git::parse_rev_list_output(&output, &process);
self.version_date =
chrono::DateTime::parse_from_str(version_date_str.trim(), "%Y-%m-%d %H:%M:%S %z")
- .map(|dt| dt.with_timezone(&chrono::Utc))
- .unwrap_or_else(|_| chrono::Utc::now());
+ .map(|dt| dt.with_timezone(&chrono::Utc))?;
let mut git_describe_output = String::new();
if process.borrow_mut().execute_args(
@@ -298,7 +297,12 @@ impl Compiler {
// re-sign the phar with reproducible timestamp / signature
let mut util = Timestamps::new(phar_file);
- util.update_timestamps(&self.version_date.format("%Y-%m-%d %H:%M:%S").to_string())?;
+ util.update_timestamps(
+ &self
+ .version_date
+ .format(date_format_to_strftime("Y-m-d H:i:s"))
+ .to_string(),
+ )?;
util.save(phar_file, Phar::SHA512)?;
Linter::lint(
@@ -355,7 +359,9 @@ impl Compiler {
);
replacements.insert(
"@release_date@".to_string(),
- self.version_date.format("%Y-%m-%d %H:%M:%S").to_string(),
+ self.version_date
+ .format(date_format_to_strftime("Y-m-d H:i:s"))
+ .to_string(),
);
content = strtr_array(&content, &replacements);
content = Preg::replace(
diff --git a/crates/shirabe/src/package/dumper/array_dumper.rs b/crates/shirabe/src/package/dumper/array_dumper.rs
index 4217308..27fc415 100644
--- a/crates/shirabe/src/package/dumper/array_dumper.rs
+++ b/crates/shirabe/src/package/dumper/array_dumper.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Package/Dumper/ArrayDumper.php
use indexmap::IndexMap;
-use shirabe_php_shim::PhpMixed;
+use shirabe_php_shim::{DATE_RFC3339, PhpMixed};
use crate::package::Mirror;
use crate::package::PackageInterfaceHandle;
@@ -156,7 +156,7 @@ impl ArrayDumper {
if let Some(release_date) = package.get_release_date() {
data.insert(
"time".to_string(),
- PhpMixed::String(release_date.to_rfc3339()),
+ PhpMixed::String(release_date.format(DATE_RFC3339).to_string()),
);
}
diff --git a/crates/shirabe/src/package/loader/array_loader.rs b/crates/shirabe/src/package/loader/array_loader.rs
index d2aeac6..4df022b 100644
--- a/crates/shirabe/src/package/loader/array_loader.rs
+++ b/crates/shirabe/src/package/loader/array_loader.rs
@@ -1,12 +1,12 @@
//! ref: composer/src/Composer/Package/Loader/ArrayLoader.php
use anyhow::Result;
-use chrono::{DateTime, TimeZone, Utc};
+use chrono::Utc;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_php_shim::{
- E_USER_DEPRECATED, Exception, PhpMixed, UnexpectedValueException, is_scalar, is_string,
- json_encode, ltrim, sprintf, stripos, strpos, strtolower, strval, substr, trigger_error, trim,
+ E_USER_DEPRECATED, PhpMixed, UnexpectedValueException, is_scalar, is_string, json_encode,
+ ltrim, sprintf, stripos, strpos, strtolower, strval, substr, trigger_error, trim,
};
use crate::package::CompleteAliasPackageHandle;
@@ -527,14 +527,7 @@ impl ArrayLoader {
time_str.to_string()
};
- let result: std::result::Result<DateTime<Utc>, Exception> =
- // TODO(phase-b): port PHP `new \DateTime($time, new \DateTimeZone('UTC'))`
- Utc.datetime_from_str(&time, "%Y-%m-%dT%H:%M:%S%z")
- .map_err(|e| Exception {
- message: e.to_string(),
- code: 0,
- });
- if let Ok(date) = result {
+ if let Ok(date) = shirabe_php_shim::date_create::<Utc>(&time) {
package.package_mut().set_release_date(Some(date));
}
}
diff --git a/crates/shirabe/src/package/loader/validating_array_loader.rs b/crates/shirabe/src/package/loader/validating_array_loader.rs
index 4994d5a..e6db19e 100644
--- a/crates/shirabe/src/package/loader/validating_array_loader.rs
+++ b/crates/shirabe/src/package/loader/validating_array_loader.rs
@@ -6,10 +6,10 @@ use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
use shirabe_external_packages::composer::spdx_licenses::SpdxLicenses;
use shirabe_php_shim::{
- E_USER_DEPRECATED, Exception, FILTER_VALIDATE_EMAIL, PHP_EOL, PhpMixed, array_intersect_key,
- array_values, filter_var, get_debug_type, is_array, is_bool, is_int, is_numeric, is_scalar,
- is_string, json_encode, parse_url_all, php_to_string, sprintf, str_replace, strcasecmp,
- strtolower, strtotime, substr, trigger_error, trim, var_export,
+ E_USER_DEPRECATED, FILTER_VALIDATE_EMAIL, PHP_EOL, PhpMixed, array_intersect_key, array_values,
+ filter_var, get_debug_type, is_array, is_bool, is_int, is_numeric, is_scalar, is_string,
+ json_encode, parse_url_all, php_to_string, sprintf, str_replace, strcasecmp, strtolower,
+ strtotime, substr, trigger_error, trim, var_export,
};
use shirabe_semver::constraint::AnyConstraint;
use shirabe_semver::constraint::MatchNoneConstraint;
@@ -166,7 +166,7 @@ impl ValidatingArrayLoader {
self.validate_string("time", false);
if self.config.contains_key("time") {
let time_str = self.config["time"].as_string().unwrap_or("").to_string();
- match Self::parse_datetime_utc(&time_str) {
+ match shirabe_php_shim::date_create::<chrono::Utc>(&time_str) {
Ok(dt) => {
release_date = Some(dt);
}
@@ -1591,22 +1591,4 @@ impl ValidatingArrayLoader {
None => true,
}
}
-
- fn parse_datetime_utc(s: &str) -> anyhow::Result<chrono::DateTime<chrono::Utc>> {
- // TODO(phase-b): PHP's `new \DateTime($s, new \DateTimeZone('UTC'))` accepts
- // many free-form formats; approximate with chrono for now.
- if let Ok(dt) = chrono::DateTime::parse_from_rfc3339(s) {
- return Ok(dt.with_timezone(&chrono::Utc));
- }
- if let Ok(dt) = chrono::NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S") {
- return Ok(chrono::Utc.from_utc_datetime(&dt));
- }
- if let Ok(d) = chrono::NaiveDate::parse_from_str(s, "%Y-%m-%d") {
- return Ok(chrono::Utc.from_utc_datetime(&d.and_hms_opt(0, 0, 0).unwrap()));
- }
- Err(anyhow::anyhow!(Exception {
- message: format!("Failed to parse date: {}", s),
- code: 0,
- }))
- }
}
diff --git a/crates/shirabe/src/package/locker.rs b/crates/shirabe/src/package/locker.rs
index 5f13a31..2546780 100644
--- a/crates/shirabe/src/package/locker.rs
+++ b/crates/shirabe/src/package/locker.rs
@@ -876,7 +876,6 @@ impl Locker {
None,
);
if Preg::is_match(r"{^\s*\d+\s*$}", &output_str).unwrap_or(false) {
- // TODO(phase-b): new \DateTime('@'.trim($output), new \DateTimeZone('UTC'))
let ts = trim(&output_str, None).parse::<i64>().unwrap_or(0);
datetime = chrono::DateTime::from_timestamp(ts, 0);
}
diff --git a/crates/shirabe/src/repository/vcs/forgejo_driver.rs b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
index a40f6a9..73975cd 100644
--- a/crates/shirabe/src/repository/vcs/forgejo_driver.rs
+++ b/crates/shirabe/src/repository/vcs/forgejo_driver.rs
@@ -5,7 +5,7 @@ use anyhow::Result;
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
- PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, urlencode,
+ DATE_RFC3339, PhpMixed, RuntimeException, base64_decode, explode, extension_loaded, urlencode,
};
use crate::cache::Cache;
@@ -185,7 +185,7 @@ impl ForgejoDriver {
pub fn get_change_date(
&mut self,
identifier: &str,
- ) -> Result<Option<chrono::DateTime<chrono::Utc>>> {
+ ) -> Result<Option<chrono::DateTime<chrono::FixedOffset>>> {
if let Some(ref mut git_driver) = self.git_driver {
return git_driver.get_change_date(identifier);
}
@@ -218,8 +218,7 @@ impl ForgejoDriver {
code: 0,
})?;
- let date = chrono::DateTime::parse_from_rfc3339(&date_str)
- .map(|d| d.with_timezone(&chrono::Utc))?;
+ let date: chrono::DateTime<chrono::FixedOffset> = shirabe_php_shim::date_create(&date_str)?;
Ok(Some(date))
}
@@ -725,7 +724,7 @@ impl crate::repository::vcs::VcsDriverInterface for ForgejoDriver {
fn get_change_date(
&mut self,
identifier: &str,
- ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
+ ) -> anyhow::Result<Option<chrono::DateTime<chrono::FixedOffset>>> {
ForgejoDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/fossil_driver.rs b/crates/shirabe/src/repository/vcs/fossil_driver.rs
index 0ee20da..15328c0 100644
--- a/crates/shirabe/src/repository/vcs/fossil_driver.rs
+++ b/crates/shirabe/src/repository/vcs/fossil_driver.rs
@@ -1,10 +1,12 @@
//! ref: composer/src/Composer/Repository/Vcs/FossilDriver.php
use crate::io::io_interface;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable};
+use shirabe_php_shim::{
+ DATE_RFC3339, PhpMixed, RuntimeException, dirname, is_dir, is_file, is_writable,
+};
use crate::cache::Cache;
use crate::config::Config;
@@ -256,7 +258,10 @@ impl FossilDriver {
Ok(Some(content))
}
- pub fn get_change_date(&self, _identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(
+ &self,
+ _identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
let mut output = String::new();
self.inner.process.borrow_mut().execute_args(
&["fossil", "finfo", "-b", "-n", "1", "composer.json"]
@@ -268,8 +273,8 @@ impl FossilDriver {
let parts: Vec<&str> = output.trim().splitn(3, ' ').collect();
let date = parts.get(1).copied().unwrap_or("");
- let date = DateTime::parse_from_rfc3339(date).map(|d| d.with_timezone(&Utc))?;
- Ok(Some(date))
+ let date: DateTime<Utc> = shirabe_php_shim::date_create(date)?;
+ Ok(Some(date.fixed_offset()))
}
pub fn get_tags(&mut self) -> anyhow::Result<IndexMap<String, String>> {
@@ -383,7 +388,10 @@ impl crate::repository::vcs::VcsDriverInterface for FossilDriver {
FossilDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
FossilDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
index f8cfd7a..de1f814 100644
--- a/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_bitbucket_driver.rs
@@ -2,13 +2,13 @@
use crate::io::io_interface;
use anyhow::Result;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
- InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_key_exists,
- array_search_mixed, extension_loaded, http_build_query_mixed, implode, in_array, is_array,
- sprintf, strpos,
+ DATE_RFC3339, InvalidArgumentException, LogicException, PhpMixed, RuntimeException,
+ array_key_exists, array_search_mixed, extension_loaded, http_build_query_mixed, implode,
+ in_array, is_array, sprintf, strpos,
};
use crate::cache::Cache;
@@ -461,7 +461,7 @@ impl GitBitbucketDriver {
}
/// @inheritDoc
- pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<FixedOffset>>> {
if let Some(fallback) = self.fallback_driver.as_mut() {
return fallback.get_change_date(identifier);
}
@@ -486,11 +486,8 @@ impl GitBitbucketDriver {
.fetch_with_oauth_credentials(&resource, false)?
.decode_json()?;
- // TODO(phase-b): port PHP `new \DateTimeImmutable($commit['date'])`
let date_str = commit.get("date").and_then(|v| v.as_string()).unwrap_or("");
- let date: DateTime<Utc> = chrono::DateTime::parse_from_rfc3339(date_str)
- .map_err(|e| anyhow::anyhow!(e))?
- .with_timezone(&Utc);
+ let date: DateTime<FixedOffset> = shirabe_php_shim::date_create(date_str)?;
Ok(Some(date))
}
@@ -920,7 +917,10 @@ impl crate::repository::vcs::VcsDriverInterface for GitBitbucketDriver {
GitBitbucketDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
GitBitbucketDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs
index 4878ffe..7f8c206 100644
--- a/crates/shirabe/src/repository/vcs/git_driver.rs
+++ b/crates/shirabe/src/repository/vcs/git_driver.rs
@@ -2,7 +2,7 @@
use crate::io::io_interface;
use chrono::TimeZone;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
@@ -281,7 +281,10 @@ impl GitDriver {
Ok(Some(content))
}
- pub fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
return Err(RuntimeException {
message: format!(
@@ -310,7 +313,9 @@ impl GitDriver {
let timestamp_str = GitUtil::parse_rev_list_output(&output, &self.inner.process);
let timestamp: i64 = timestamp_str.trim().parse().unwrap_or(0);
- Ok(Some(Utc.timestamp_opt(timestamp, 0).unwrap()))
+ Ok(Some(
+ Utc.timestamp_opt(timestamp, 0).unwrap().fixed_offset(),
+ ))
}
pub fn get_tags(&mut self) -> anyhow::Result<IndexMap<String, String>> {
@@ -514,7 +519,10 @@ impl crate::repository::vcs::VcsDriverInterface for GitDriver {
GitDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
GitDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/github_driver.rs b/crates/shirabe/src/repository/vcs/github_driver.rs
index 45ba7b7..aa1e135 100644
--- a/crates/shirabe/src/repository/vcs/github_driver.rs
+++ b/crates/shirabe/src/repository/vcs/github_driver.rs
@@ -2,13 +2,14 @@
use crate::io::io_interface;
use anyhow::Result;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
- InvalidArgumentException, PhpMixed, RuntimeException, array_diff, array_key_exists, array_map,
- array_search_mixed, base64_decode, basename, count, empty, explode, extension_loaded, in_array,
- parse_url_all, sprintf, strpos, strtolower, substr, trim, urlencode,
+ DATE_RFC3339, InvalidArgumentException, PhpMixed, RuntimeException, array_diff,
+ array_key_exists, array_map, array_search_mixed, base64_decode, basename, count, empty,
+ explode, extension_loaded, in_array, parse_url_all, sprintf, strpos, strtolower, substr, trim,
+ urlencode,
};
use crate::cache::Cache;
@@ -821,7 +822,7 @@ impl GitHubDriver {
Ok(Some(content))
}
- pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<FixedOffset>>> {
if let Some(ref mut git_driver) = self.git_driver {
return git_driver.get_change_date(identifier);
}
@@ -851,11 +852,8 @@ impl GitHubDriver {
_ => String::new(),
};
- Ok(Some(
- DateTime::parse_from_rfc3339(&date_str)
- .map(|dt| dt.with_timezone(&Utc))
- .unwrap_or_else(|_| Utc::now()),
- ))
+ let date: DateTime<FixedOffset> = shirabe_php_shim::date_create(&date_str)?;
+ Ok(Some(date))
}
pub fn get_tags(&mut self) -> Result<IndexMap<String, String>> {
@@ -1364,7 +1362,10 @@ impl crate::repository::vcs::VcsDriverInterface for GitHubDriver {
GitHubDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
GitHubDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/gitlab_driver.rs b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
index 97dcc30..8ab30d4 100644
--- a/crates/shirabe/src/repository/vcs/gitlab_driver.rs
+++ b/crates/shirabe/src/repository/vcs/gitlab_driver.rs
@@ -2,13 +2,13 @@
use crate::io::io_interface;
use anyhow::Result;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
- InvalidArgumentException, LogicException, PhpMixed, RuntimeException, array_search_mixed,
- array_shift, ctype_alnum, empty, explode, extension_loaded, implode, in_array, is_array,
- is_string, ord, sprintf, strpos, strtolower,
+ DATE_RFC3339, InvalidArgumentException, LogicException, PhpMixed, RuntimeException,
+ array_search_mixed, array_shift, ctype_alnum, empty, explode, extension_loaded, implode,
+ in_array, is_array, is_string, ord, sprintf, strpos, strtolower,
};
use crate::cache::Cache;
@@ -458,7 +458,7 @@ impl GitLabDriver {
Ok(content)
}
- pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<FixedOffset>>> {
if let Some(ref mut git_driver) = self.git_driver {
return git_driver.get_change_date(identifier);
}
@@ -468,11 +468,8 @@ impl GitLabDriver {
.get("committed_date")
.and_then(|v| v.as_string())
.unwrap_or("");
- return Ok(Some(
- DateTime::parse_from_rfc3339(committed_date)
- .map(|dt| dt.with_timezone(&Utc))
- .unwrap_or_else(|_| Utc::now()),
- ));
+ let date: DateTime<FixedOffset> = shirabe_php_shim::date_create(committed_date)?;
+ return Ok(Some(date));
}
Ok(None)
@@ -1153,7 +1150,10 @@ impl crate::repository::vcs::VcsDriverInterface for GitLabDriver {
GitLabDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
GitLabDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/hg_driver.rs b/crates/shirabe/src/repository/vcs/hg_driver.rs
index c35a574..f637437 100644
--- a/crates/shirabe/src/repository/vcs/hg_driver.rs
+++ b/crates/shirabe/src/repository/vcs/hg_driver.rs
@@ -10,10 +10,10 @@ use crate::repository::vcs::VcsDriverBase;
use crate::util::Filesystem;
use crate::util::Hg as HgUtils;
use crate::util::Url;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
-use shirabe_php_shim::{PhpMixed, RuntimeException, dirname, is_dir, is_writable};
+use shirabe_php_shim::{DATE_RFC3339, PhpMixed, RuntimeException, dirname, is_dir, is_writable};
#[derive(Debug)]
pub struct HgDriver {
@@ -197,7 +197,10 @@ impl HgDriver {
Ok(Some(content))
}
- pub fn get_change_date(&self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(
+ &self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
if identifier.starts_with('-') {
return Err(RuntimeException {
message: format!(
@@ -225,8 +228,8 @@ impl HgDriver {
Some(self.repo_dir.clone()),
);
- let date = DateTime::parse_from_rfc3339(output.trim()).map(|d| d.with_timezone(&Utc))?;
- Ok(Some(date))
+ let date: DateTime<Utc> = shirabe_php_shim::date_create(output.trim())?;
+ Ok(Some(date.fixed_offset()))
}
pub fn get_tags(&mut self) -> anyhow::Result<IndexMap<String, String>> {
@@ -410,7 +413,10 @@ impl crate::repository::vcs::VcsDriverInterface for HgDriver {
HgDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
HgDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/perforce_driver.rs b/crates/shirabe/src/repository/vcs/perforce_driver.rs
index 0fe0f6f..65f2856 100644
--- a/crates/shirabe/src/repository/vcs/perforce_driver.rs
+++ b/crates/shirabe/src/repository/vcs/perforce_driver.rs
@@ -113,7 +113,7 @@ impl PerforceDriver {
pub fn get_change_date(
&self,
_identifier: &str,
- ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
+ ) -> anyhow::Result<Option<chrono::DateTime<chrono::FixedOffset>>> {
Ok(None)
}
@@ -248,7 +248,7 @@ impl crate::repository::vcs::VcsDriverInterface for PerforceDriver {
fn get_change_date(
&mut self,
identifier: &str,
- ) -> anyhow::Result<Option<chrono::DateTime<chrono::Utc>>> {
+ ) -> anyhow::Result<Option<chrono::DateTime<chrono::FixedOffset>>> {
PerforceDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/svn_driver.rs b/crates/shirabe/src/repository/vcs/svn_driver.rs
index ef8787a..f4e2bba 100644
--- a/crates/shirabe/src/repository/vcs/svn_driver.rs
+++ b/crates/shirabe/src/repository/vcs/svn_driver.rs
@@ -1,7 +1,7 @@
//! ref: composer/src/Composer/Repository/Vcs/SvnDriver.php
use anyhow::Result;
-use chrono::{DateTime, TimeZone, Utc};
+use chrono::{DateTime, FixedOffset, Utc};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{
@@ -296,7 +296,7 @@ impl SvnDriver {
Ok(Some(output))
}
- pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<Utc>>> {
+ pub fn get_change_date(&mut self, identifier: &str) -> Result<Option<DateTime<FixedOffset>>> {
let identifier = format!("/{}/", trim(identifier, Some("/")));
let (path, rev) = if let Ok(Some(m)) =
@@ -329,10 +329,9 @@ impl SvnDriver {
.unwrap_or(false)
{
let date_str = m.get(&CaptureKey::ByIndex(1)).cloned().unwrap_or_default();
- // PHP: new \DateTimeImmutable($match[1], new \DateTimeZone('UTC'))
- return Ok(Utc
- .datetime_from_str(date_str.trim(), "%Y-%m-%d %H:%M:%S %z")
- .ok());
+ return Ok(shirabe_php_shim::date_create::<Utc>(date_str.trim())
+ .ok()
+ .map(|d| d.fixed_offset()));
}
}
}
@@ -638,7 +637,10 @@ impl crate::repository::vcs::VcsDriverInterface for SvnDriver {
SvnDriver::get_file_content(self, file, identifier)
}
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>> {
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>> {
SvnDriver::get_change_date(self, identifier)
}
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver.rs b/crates/shirabe/src/repository/vcs/vcs_driver.rs
index 94c3ff8..dc88387 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver.rs
@@ -1,9 +1,9 @@
//! ref: composer/src/Composer/Repository/Vcs/VcsDriver.php
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_external_packages::composer::pcre::Preg;
-use shirabe_php_shim::{PhpMixed, extension_loaded};
+use shirabe_php_shim::{DATE_RFC3339, PhpMixed, extension_loaded};
use crate::cache::Cache;
use crate::config::Config;
@@ -94,7 +94,7 @@ impl VcsDriverBase {
pub fn finish_base_composer_information(
identifier: &str,
composer_file_content: Option<String>,
- change_date: impl FnOnce() -> anyhow::Result<Option<DateTime<Utc>>>,
+ change_date: impl FnOnce() -> anyhow::Result<Option<DateTime<FixedOffset>>>,
) -> anyhow::Result<Option<IndexMap<String, PhpMixed>>> {
let content = match composer_file_content {
None => return Ok(None),
@@ -123,7 +123,10 @@ impl VcsDriverBase {
.map_or(true, |v| v.as_string().map_or(true, |s| s.is_empty()))
{
if let Some(d) = change_date()? {
- composer.insert("time".to_string(), PhpMixed::String(d.to_rfc3339()));
+ composer.insert(
+ "time".to_string(),
+ PhpMixed::String(d.format(DATE_RFC3339).to_string()),
+ );
}
}
@@ -284,7 +287,7 @@ pub trait VcsDriver: VcsDriverInterface {
if let Some(change_date) = self.get_change_date(identifier)? {
composer.insert(
"time".to_string(),
- PhpMixed::String(change_date.to_rfc3339()),
+ PhpMixed::String(change_date.format(DATE_RFC3339).to_string()),
);
}
}
diff --git a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
index e845300..5d2be04 100644
--- a/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
+++ b/crates/shirabe/src/repository/vcs/vcs_driver_interface.rs
@@ -2,7 +2,7 @@
use crate::config::Config;
use crate::io::IOInterface;
-use chrono::{DateTime, Utc};
+use chrono::{DateTime, FixedOffset};
use indexmap::IndexMap;
use shirabe_php_shim::PhpMixed;
use std::cell::RefCell;
@@ -18,7 +18,10 @@ pub trait VcsDriverInterface: std::fmt::Debug {
fn get_file_content(&mut self, file: &str, identifier: &str) -> anyhow::Result<Option<String>>;
- fn get_change_date(&mut self, identifier: &str) -> anyhow::Result<Option<DateTime<Utc>>>;
+ fn get_change_date(
+ &mut self,
+ identifier: &str,
+ ) -> anyhow::Result<Option<DateTime<FixedOffset>>>;
fn get_root_identifier(&mut self) -> anyhow::Result<String>;