@@ -37,6 +37,7 @@ class Backup {
3737 private execFinishCmd : string ;
3838 private suppressErrorMsgUntil : number ;
3939 private execPromise = promisify ( exec ) ;
40+ private fsWorkaroundLinux : boolean ;
4041
4142 constructor ( ) {
4243 this . log = backupLogging ;
@@ -263,10 +264,56 @@ class Backup {
263264 ) ;
264265 }
265266
267+ private async getProfileName ( profileRootDir : string , rootProfileDir : string ) {
268+ // We assume that Joplin's profile structure is the following
269+ // rootProfileDir/
270+ // | profileDir/
271+ // | | [[profile content]]
272+ // or, if using the default,
273+ // rootProfileDir/
274+ // | [[profile content]]
275+
276+ let profileName = path . basename ( rootProfileDir ) ;
277+ if ( rootProfileDir === profileRootDir ) {
278+ profileName = "default" ;
279+ }
280+
281+ return profileName ;
282+ }
283+
284+ private async getInstanceInfo ( ) {
285+ this . log . verbose ( "getInstanceInfo" ) ;
286+
287+ const altInstanceId = await joplin . settings . globalValue ( "altInstanceId" ) ;
288+
289+ const profileDir = await joplin . settings . globalValue ( "profileDir" ) ;
290+ const rootProfileDir = await joplin . settings . globalValue ( "rootProfileDir" ) ;
291+
292+ let env = "" ;
293+ if ( ( await joplin . settings . globalValue ( "env" ) ) === "dev" ) {
294+ env = "dev" ;
295+ }
296+
297+ const profileName = await this . getProfileName ( rootProfileDir , profileDir ) ;
298+
299+ const data = {
300+ env : env ,
301+ altInstanceId : altInstanceId ,
302+ profileName : profileName ,
303+ rootProfileDir : rootProfileDir ,
304+ profileDir : profileDir ,
305+ } ;
306+ for ( const [ key , value ] of Object . entries ( data ) ) {
307+ this . log . verbose ( `${ key } :` , value ) ;
308+ }
309+ return data ;
310+ }
311+
266312 private async loadBackupPath ( ) {
267313 this . log . verbose ( "loadBackupPath" ) ;
314+ const instanceInfo = await this . getInstanceInfo ( ) ;
268315 const pathSetting = await joplin . settings . value ( "path" ) ;
269- const profileDir = await joplin . settings . globalValue ( "profileDir" ) ;
316+ const profileDir = instanceInfo [ "profileDir" ] ;
270317
271318 if ( path . isAbsolute ( pathSetting ) ) {
272319 this . backupBasePath = path . normalize ( pathSetting ) ;
@@ -302,28 +349,15 @@ class Backup {
302349 this . readmeOutputDirectory = this . backupBasePath ;
303350
304351 if ( this . createSubfolderPerProfile ) {
305- this . log . verbose ( "append profile subfolder" ) ;
306- // We assume that Joplin's profile structure is the following
307- // rootProfileDir/
308- // | profileDir/
309- // | | [[profile content]]
310- // or, if using the default,
311- // rootProfileDir/
312- // | [[profile content]]
313- const profileRootDir = await joplin . settings . globalValue (
314- "rootProfileDir"
315- ) ;
316- const profileCurrentDir = await joplin . settings . globalValue ( "profileDir" ) ;
352+ this . log . verbose ( "append profile / instance subfolder" ) ;
317353
318- let profileName = path . basename ( profileCurrentDir ) ;
319- if ( profileCurrentDir === profileRootDir ) {
320- profileName = "default ";
354+ let profileName = "" ;
355+ if ( instanceInfo [ "altInstanceId" ] !== "" ) {
356+ profileName += instanceInfo [ "altInstanceId" ] + "_ ";
321357 }
322-
323- // Appending a -dev to the profile name prevents a devmode default Joplin
324- // profile from overwriting a non-devmode Joplin profile.
325- if ( ( await joplin . settings . globalValue ( "env" ) ) === "dev" ) {
326- profileName += "-dev" ;
358+ profileName += instanceInfo [ "profileName" ] ;
359+ if ( instanceInfo [ "env" ] !== "" ) {
360+ profileName += "-" + instanceInfo [ "env" ] ;
327361 }
328362
329363 this . backupBasePath = path . join ( this . backupBasePath , profileName ) ;
@@ -372,6 +406,7 @@ class Backup {
372406 this . singleJex = await joplin . settings . value ( "singleJexV2" ) ;
373407 this . exportFormat = await joplin . settings . value ( "exportFormat" ) ;
374408 this . execFinishCmd = ( await joplin . settings . value ( "execFinishCmd" ) ) . trim ( ) ;
409+ this . fsWorkaroundLinux = await joplin . settings . value ( "fsWorkaroundLinux" ) ;
375410
376411 this . backupPlugins = await joplin . settings . value ( "backupPlugins" ) ;
377412
@@ -488,8 +523,8 @@ class Backup {
488523 "backupVersion" ,
489524 "backupPlugins" ,
490525 "createSubfolder" ,
491- "createSubfolder" ,
492526 "exportFormat" ,
527+ "fsWorkaroundLinux" ,
493528 ] ;
494529
495530 this . log . verbose ( "Plugin settings:" ) ;
@@ -613,6 +648,7 @@ class Backup {
613648 }
614649
615650 private async makeBackupSet ( ) : Promise < string > {
651+ this . log . verbose ( "makeBackupSet" ) ;
616652 let backupDst = "" ;
617653 if ( this . zipArchive === "no" && this . passwordEnabled === false ) {
618654 if ( this . backupRetention > 1 ) {
@@ -626,6 +662,7 @@ class Backup {
626662 backupDst = await this . moveFinishedBackup ( ) ;
627663 }
628664 } else {
665+ this . log . verbose ( "Bakupset as zip" ) ;
629666 const zipFile = await this . createZipArchive ( ) ;
630667 if ( this . backupRetention > 1 ) {
631668 backupDst = await this . moveFinishedBackup ( zipFile ) ;
@@ -746,7 +783,11 @@ class Backup {
746783 await this . addToZipArchive ( logDst , logFile , this . password , [ "-sdel" ] ) ;
747784 } else {
748785 try {
749- fs . moveSync ( logFile , path . join ( logDst , logfileName ) ) ;
786+ await helper . WorkaroundMove (
787+ logFile ,
788+ path . join ( logDst , logfileName ) ,
789+ this . fsWorkaroundLinux
790+ ) ;
750791 } catch ( e ) {
751792 await this . showError ( "moveLogFile: " + e . message ) ;
752793 throw e ;
@@ -1058,7 +1099,7 @@ class Backup {
10581099 if ( fs . existsSync ( src ) ) {
10591100 this . log . verbose ( "Copy " + src ) ;
10601101 try {
1061- fs . copySync ( src , dst ) ;
1102+ await helper . WorkaroundCopyFile ( src , dst , this . fsWorkaroundLinux ) ;
10621103 return true ;
10631104 } catch ( e ) {
10641105 await this . showError (
@@ -1076,10 +1117,12 @@ class Backup {
10761117 if ( fs . existsSync ( src ) ) {
10771118 this . log . verbose ( "Copy " + src ) ;
10781119 try {
1079- fs . copyFileSync ( src , dest ) ;
1120+ await helper . WorkaroundCopyFile ( src , dest , this . fsWorkaroundLinux ) ;
10801121 return true ;
10811122 } catch ( e ) {
1082- this . log . error ( "backupFile: " + e . message ) ;
1123+ await this . showError (
1124+ i18n . __ ( "msg.error.fileCopy" , "backupFile" , e . message )
1125+ ) ;
10831126 throw e ;
10841127 }
10851128 } else {
@@ -1120,7 +1163,11 @@ class Backup {
11201163 }
11211164
11221165 try {
1123- fs . moveSync ( src , backupDestination ) ;
1166+ await helper . WorkaroundMove (
1167+ src ,
1168+ backupDestination ,
1169+ this . fsWorkaroundLinux
1170+ ) ;
11241171 } catch ( e ) {
11251172 await this . showError (
11261173 i18n . __ ( "msg.error.fileCopy" , "moveFinishedBackup" , e . message )
@@ -1136,7 +1183,11 @@ class Backup {
11361183 if ( zipFile ) {
11371184 backupDestination = path . join ( this . backupBasePath , "JoplinBackup.7z" ) ;
11381185 try {
1139- fs . moveSync ( zipFile , backupDestination ) ;
1186+ await helper . WorkaroundMove (
1187+ zipFile ,
1188+ backupDestination ,
1189+ this . fsWorkaroundLinux
1190+ ) ;
11401191 } catch ( e ) {
11411192 await this . showError (
11421193 i18n . __ ( "msg.error.fileCopy" , "moveFinishedBackup" , e . message )
@@ -1151,9 +1202,12 @@ class Backup {
11511202 for ( const file of backupData ) {
11521203 let dst = path . join ( backupDestination , file ) ;
11531204 try {
1154- fs . moveSync ( path . join ( this . activeBackupPath , file ) , dst , {
1155- overwrite : true ,
1156- } ) ;
1205+ await helper . WorkaroundMove (
1206+ path . join ( this . activeBackupPath , file ) ,
1207+ dst ,
1208+ this . fsWorkaroundLinux ,
1209+ true
1210+ ) ;
11571211 } catch ( e ) {
11581212 await this . showError (
11591213 i18n . __ ( "msg.error.fileCopy" , "moveFinishedBackup" , e . message )
0 commit comments