← Back to team overview

kicad-developers team mailing list archive

Re: [RFC] Able to install KiCad stable and "daily build" in same computer

 

Attached is a patch for discussion only.

Its the minimum change I could come up with to implement a unique version specific config directory.

Nick mentioned changing XDG_CONFIG_HOME, that will not work on Windows or Mac. And on Linux, etc it will change from "~/.config/kicad" to "~/somethingelse/kicad" which would work, but isn't a very friendly naming scheme.

So, what I did is:
Define a previous config dir and a current one.  They can not be sub directories of one another, so I went with "kicad.v5" for the new config directory.  For a nightly we could use "kicad.v6dev" or some such.

HOW these constants should get assigned I don't know.  At the moment I hard coded them.

I changed GetKicadConfigPath() to take a parameter of the config subdirectory, and renamed the function to just GetConfigPath(). Added a new GetKicadConfigPath() which works like the old one, but uses the new parametrised GetConfigPath(). IF the current config path does not exist, we make it (Same functionality as before), except then we check if the old one exists, and if it does, we just copy everything from it into the new one, once.  If the new config path already exists we ignore the old one all together.

Very first time this runs will be slower than normal (due to the file copy), every other time it should be exactly the same as it is now.

As far as I know wx does not have a copy directories function, but there is one in their forums, so I pulled that, and made some small changes to remove redundancy in the code.  Its a pretty straight forward recursive copy.  I don't know if this should stay in this file, or live elsewhere, or be re-written/re-named.

Patch attached.  Tested on Linux, and seems to work fine.  Should work on Windows and MAC, but I haven't tested on those.  ALL programs use the GetKicadConfigPath() function to get the base of the configuration (as far as I can tell), there should be no strange corner cases.


diff --git a/common/common.cpp b/common/common.cpp
index c547b60f3..77002f473 100644
--- a/common/common.cpp
+++ b/common/common.cpp
@@ -40,6 +40,7 @@
 #include <wx/utils.h>
 #include <wx/stdpaths.h>
 #include <wx/url.h>
+#include <wx/dir.h>
 
 #include <pgm_base.h>
 
@@ -215,7 +216,57 @@ wxConfigBase* GetNewConfig( const wxString& aProgName )
 }
 
 
-wxString GetKicadConfigPath()
+// Taken from:
+//    https://forums.wxwidgets.org/viewtopic.php?t=2080
+//    Slightly modified for kicad use.
+bool wxCopyDir(wxString sFrom, wxString sTo, bool noFromOK = false)
+{
+    // Fix paths
+    if (sFrom[sFrom.Len() - 1] != '\\' && sFrom[sFrom.Len() - 1] != '/') sFrom += wxFILE_SEP_PATH;
+    if (sTo[sTo.Len() - 1] != '\\' && sTo[sTo.Len() - 1] != '/') sTo += wxFILE_SEP_PATH;
+
+    // Make destination directory
+    if (!wxDirExists(sTo)) {
+        if (!wxFileName::Mkdir(sTo, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL)) {
+            wxLogError(wxT("%s could not be created!"), sTo.c_str());
+            return false;
+        }
+    }
+
+    // Check if source directory exists
+    if (!::wxDirExists(sFrom)) {
+        if (noFromOK) return true;
+        wxLogError(wxT("%s does not exist!\r\nCan not copy directory"), sFrom.c_str());
+        return false;
+    }
+
+    // Copy from Source to Destination
+    wxDir fDir(sFrom);
+    wxString sNext = wxEmptyString;
+    bool bIsFile = fDir.GetFirst(&sNext);
+    while (bIsFile) {
+        const wxString sFileFrom = sFrom + sNext;
+        const wxString sFileTo = sTo + sNext;
+        if (::wxDirExists(sFileFrom)) {
+            wxCopyDir(sFileFrom, sFileTo);
+        }
+        else {
+            if (!::wxFileExists(sFileTo)) {
+                if (!::wxCopyFile(sFileFrom, sFileTo)) {
+                    wxLogError(wxT("Could not copy %s to %s !"), sFileFrom.c_str(), sFileTo.c_str());
+                    return false;
+                }
+            }
+        }
+        bIsFile = fDir.GetNext(&sNext);
+    }
+    return true;
+}
+
+#define KICAD_PREVIOUS_CONFIG wxT( "kicad" )
+#define KICAD_CURRENT_CONFIG  wxT( "kicad.v5" )
+
+wxFileName GetConfigPath( wxString name )
 {
     wxFileName cfgpath;
 
@@ -240,11 +291,24 @@ wxString GetKicadConfigPath()
     }
 #endif
 
-    cfgpath.AppendDir( wxT( "kicad" ) );
+    cfgpath.AppendDir( name );
+
+    return cfgpath;
+}
+
+
+wxString GetKicadConfigPath()
+{
+    wxFileName cfgpath;
+
+    cfgpath = GetConfigPath( KICAD_CURRENT_CONFIG );
 
     if( !cfgpath.DirExists() )
     {
-        cfgpath.Mkdir( wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
+        // No Current Config, so get the path of the previous config.
+        // and copy everything from it.
+        wxCopyDir( GetConfigPath( KICAD_PREVIOUS_CONFIG ).GetPath(), 
+                   cfgpath.GetPath(), true );
     }
 
     return cfgpath.GetPath();

Follow ups

References