7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-11 14:50:11 +00:00

CHANGED: Backup project only when different

Makes a test backup file and compares to the existing zip file backup to
see if the files have changed since it was made.  If so, the new file is
kept.  If not, we discard the new file and continue

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12453
This commit is contained in:
Harry Best 2022-09-25 12:51:20 +01:00 committed by Seth Hillbrand
parent 9177e62718
commit cc5fb60d93
3 changed files with 72 additions and 10 deletions

View File

@ -33,14 +33,47 @@
#include <wxstream_helper.h>
#include <wx/log.h>
#include <set>
#define ZipFileExtension wxT( "zip" )
PROJECT_ARCHIVER::PROJECT_ARCHIVER()
{
}
bool PROJECT_ARCHIVER::AreZipArchivesIdentical( const wxString& aZipFileA,
const wxString& aZipFileB, REPORTER& aReporter )
{
wxFFileInputStream streamA( aZipFileA );
wxFFileInputStream streamB( aZipFileB );
if( !streamA.IsOk() || !streamB.IsOk() )
{
aReporter.Report( _( "Could not open archive file." ), RPT_SEVERITY_ERROR );
return false;
}
wxZipInputStream zipStreamA = wxZipInputStream( streamA );
wxZipInputStream zipStreamB = wxZipInputStream( streamB );
std::set<wxUint32> crcsA;
std::set<wxUint32> crcsB;
for( wxZipEntry* entry = zipStreamA.GetNextEntry(); entry; entry = zipStreamA.GetNextEntry() )
{
crcsA.insert( entry->GetCrc() );
}
for( wxZipEntry* entry = zipStreamB.GetNextEntry(); entry; entry = zipStreamB.GetNextEntry() )
{
crcsB.insert( entry->GetCrc() );
}
return crcsA == crcsB;
}
// Unarchive Files code comes from wxWidgets sample/archive/archive.cpp
bool PROJECT_ARCHIVER::Unarchive( const wxString& aSrcFile, const wxString& aDestDir,

View File

@ -1339,17 +1339,36 @@ bool SETTINGS_MANAGER::TriggerBackupIfNeeded( REPORTER& aReporter ) const
return first.GetTicks() > second.GetTicks();
} );
// Do we even need to back up?
if( !files.empty() )
// Backup
bool backupSuccessful = BackupProject( aReporter );
if( !backupSuccessful )
return false;
// Update the file list
files.clear();
dir.Traverse( traverser, wxT( "*.zip" ) );
// Sort newest-first
std::sort( files.begin(), files.end(),
[&]( const wxString& aFirst, const wxString& aSecond ) -> bool
{
wxDateTime first = modTime( aFirst );
wxDateTime second = modTime( aSecond );
return first.GetTicks() > second.GetTicks();
} );
// Are there any changes since the last backup?
if( files.size() > 1 )
{
wxDateTime lastTime = modTime( files[0] );
PROJECT_ARCHIVER archiver;
bool identicalToPrevious =
archiver.AreZipArchivesIdentical( files[0], files[1], aReporter );
if( lastTime.IsValid() )
if( identicalToPrevious )
{
wxTimeSpan delta = wxDateTime::Now() - modTime( files[0] );
if( delta.IsShorterThan( wxTimeSpan::Seconds( settings.min_interval ) ) )
return true;
wxRemoveFile( files[0] );
return true;
}
}
@ -1413,7 +1432,7 @@ bool SETTINGS_MANAGER::TriggerBackupIfNeeded( REPORTER& aReporter ) const
wxRemoveFile( file );
}
return BackupProject( aReporter );
return true;
}

View File

@ -36,6 +36,16 @@ public:
~PROJECT_ARCHIVER() = default;
/**
* Compares the crcs of all the files in zip archive to determine whether the archives are identical
* @param aZipFileA is the full path to the first zip
* @param aZipFileB is the full path to the second zip
* @param aReporter is used to report status
* @return true if the archives are identical
*/
bool AreZipArchivesIdentical( const wxString& aZipFileA, const wxString& aZipFileB,
REPORTER& aReporter );
/**
* Creates an archive of the project
* @param aSrcFile is the full path to the project to be archived