modular_sync #4 CopyPolicy: "받는 쪽이 더 새것이면 건너뛰기" 판단을 SameFile.keepNewer 하나로
- SameFile.keepNewer(skipNewer, targetModified, modified): 설정 (229) 이 켜져 있고 받는 쪽이 2초 넘게 새것일 때만 그대로 둠, 시각을 모르면 덮음 - 부르는 곳: 폴더 합치기 (로컬 isNewerThere · 원격 anyCopy) · 압축 풀기 덮어쓰기 (archive_ops). 같은 이름 창의 "더 새것" 표시 (name_clash) 도 SameFile.targetNewer - 2초 규칙을 따로 계산하던 곳이 없어짐 (robocopy 는 /XO, rsync 는 -u 로 같은 일) - 동작은 그대로 (판단 모으기만). 약속 시험 한 줄 더함 확인: analyze 0 · 단위 1484 ×2 (c4_unit1 · c4_unit3) · 통합 6/6 ×2 · base10 214장 0px · move_left_shot · check_shot ×2 (c4_unit2 에서 ftp_test 1 · l10n_check 1 이 같은 때 실패 - 따로 3회 · 전체 다시 1회 모두 통과, 부하 때의 흔들림으로 보이며 따로 보고) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>modular
parent
81a2c169ff
commit
512d2904d2
|
|
@ -8,6 +8,7 @@ import 'package:path/path.dart' as p;
|
|||
import '../l10n/tr.dart';
|
||||
import 'file_ops.dart' show NameConflict, nameProblem;
|
||||
import '../services/platform_info.dart';
|
||||
import 'files/same_file.dart';
|
||||
|
||||
/// 86: 압축 종류 (확장자로)
|
||||
enum ArchiveKind { zip, sevenZip, rar }
|
||||
|
|
@ -142,9 +143,8 @@ class ExtractResult {
|
|||
|
||||
/// 덮어쓰기에서 건너뛸지: 받는 쪽 파일이 압축 안의 것보다 2초 넘게 새것
|
||||
bool _targetNewer(String target, DateTime? modified) {
|
||||
if (modified == null) return false;
|
||||
try {
|
||||
return File(target).lastModifiedSync().isAfter(modified.add(const Duration(seconds: 2)));
|
||||
return SameFile.keepNewer(skipNewer: true, targetModified: File(target).lastModifiedSync(), modified: modified);
|
||||
} catch (_) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ Future<List<String>> anyCopy(TransferControl c, List<String> sources, String des
|
|||
// 229: 합치는 폴더 안에서 받는 쪽이 더 새것이면 예전 것으로 덮지 않는다 (WebDAV 도 로컬과 같게)
|
||||
if (inner && c.skipNewerInMerge) {
|
||||
final t = await vStat(target);
|
||||
if (t != null && !t.isDir && SameFile.targetNewer(t.modified, st.modified)) {
|
||||
if (t != null && !t.isDir && SameFile.keepNewer(skipNewer: true, targetModified: t.modified, modified: st.modified)) {
|
||||
c.keptNewer.add(src);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ Future<void> _deleteExcept(String dir, Set<String> keep) async {
|
|||
Future<bool> isNewerThere(String src, String target) async {
|
||||
final t = File(target);
|
||||
if (!await t.exists()) return false;
|
||||
return SameFile.targetNewer(await t.lastModified(), await File(src).lastModified());
|
||||
return SameFile.keepNewer(skipNewer: true, targetModified: await t.lastModified(), modified: await File(src).lastModified());
|
||||
}
|
||||
|
||||
/// 229: 같은 이름 창 - 폴더를 합치면 안쪽에서 받는 쪽이 더 새 파일 수 ([limit] 개까지 셈, 로컬만)
|
||||
|
|
|
|||
|
|
@ -24,4 +24,9 @@ class SameFile {
|
|||
|
||||
/// 받는 쪽이 [window] 넘게 더 새것인지 (-u 건너뛰기 · 미리 보기 "더 새 것" 표시)
|
||||
static bool targetNewer(DateTime targetModified, DateTime modified) => targetModified.isAfter(modified.add(window));
|
||||
|
||||
/// modular_sync #4 CopyPolicy: 환경 설정 "받는 쪽이 더 새것이면 건너뛰기" ([skipNewer], 229) 로 받는 쪽을 그대로 둘지.
|
||||
/// 폴더 합치기 (로컬 · 원격) · 압축 풀기 (덮어쓰기) 가 모두 이것을 부른다 (robocopy 는 /XO, rsync 는 -u 로 같은 일). 받는 쪽이 없으면 false
|
||||
static bool keepNewer({required bool skipNewer, required DateTime? targetModified, required DateTime? modified}) =>
|
||||
skipNewer && targetModified != null && modified != null && targetNewer(targetModified, modified);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import '../l10n/tr.dart';
|
||||
import 'file_ops.dart' show formatSize;
|
||||
import 'vfs.dart' show vBasename;
|
||||
import 'files/same_file.dart';
|
||||
|
||||
/// 약속: 같은 이름 비교 글 ([clashCompareText]) · 파일 날짜 글 ([fileDateText]). 순수 함수, 오류 없음.
|
||||
/// 탐색기 복사 확인 창 · 끌어 놓기 · 붙여넣기가 함께 쓴다.
|
||||
|
|
@ -15,9 +16,9 @@ String clashCompareText(NameClash x) {
|
|||
final h = x.here, t = x.there;
|
||||
final newer = h == null || h.modified.year <= 1 || t.modified.year <= 1
|
||||
? ''
|
||||
: h.modified.isAfter(t.modified.add(const Duration(seconds: 2)))
|
||||
: SameFile.targetNewer(h.modified, t.modified)
|
||||
? tr(' (보낼 것이 더 새것)')
|
||||
: t.modified.isAfter(h.modified.add(const Duration(seconds: 2)))
|
||||
: SameFile.targetNewer(t.modified, h.modified)
|
||||
? tr(' (있는 것이 더 새것)')
|
||||
: tr(' (바뀐 날 같음)');
|
||||
return '${vBasename(x.src)}: ${trf('보낼 것 {0} / 있는 것 {1}', [h == null ? '?' : one(h), one(t)])}$newer';
|
||||
|
|
|
|||
|
|
@ -26,6 +26,15 @@ void main() {
|
|||
expect([SameFile.forAppSync(remote: true, move: false).uploadTime, SameFile.forAppSync(remote: true, move: true).uploadTime,
|
||||
SameFile.forAppSync(remote: false, move: false).uploadTime], [true, false, false]);
|
||||
expect([SameFile.targetNewer(t0.add(const Duration(seconds: 3)), t0), SameFile.targetNewer(t0.add(const Duration(seconds: 2)), t0)], [true, false]);
|
||||
// #4 CopyPolicy: 설정이 켜져 있고 받는 쪽이 2초 넘게 새것일 때만 그대로 둠 · 시각을 모르면 덮음
|
||||
final later = t0.add(const Duration(minutes: 1));
|
||||
expect([
|
||||
SameFile.keepNewer(skipNewer: true, targetModified: later, modified: t0),
|
||||
SameFile.keepNewer(skipNewer: false, targetModified: later, modified: t0),
|
||||
SameFile.keepNewer(skipNewer: true, targetModified: t0, modified: later),
|
||||
SameFile.keepNewer(skipNewer: true, targetModified: null, modified: t0),
|
||||
SameFile.keepNewer(skipNewer: true, targetModified: later, modified: null),
|
||||
], [true, false, false, false, false]);
|
||||
});
|
||||
|
||||
group('미리 보기 = 실제 맞추기 (받는 쪽 같은 크기 · 1분 더 새것)', () {
|
||||
|
|
|
|||
Loading…
Reference in New Issue