mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 14:16:10 -06:00
248 lines
7.5 KiB
C++
248 lines
7.5 KiB
C++
#include "SrcUpdater.h"
|
|
|
|
#define LLOG(x) //RLOG(x)
|
|
#define LDUMP(x) //RDUMP(x)
|
|
|
|
//#define IMAGECLASS IdeImg
|
|
//#define IMAGEFILE <ide/ide.iml>
|
|
//#include <Draw/iml_header.h>
|
|
|
|
void LoadUpdaterCfg(){
|
|
String cfg=ConfigFile("updates.xml");
|
|
if(FileExists(cfg)){
|
|
LoadFromXMLFile(UpdaterCfg(),cfg);
|
|
}else{
|
|
UpdaterCfg().method=0;
|
|
UpdaterCfg().sync=0;
|
|
UpdaterCfg().period=0;
|
|
UpdaterCfg().last=Null;
|
|
UpdaterCfg().ignored=0;
|
|
UpdaterCfg().localsrc=GetHomeDirFile("upp");
|
|
UpdaterCfg().svnserver="http://upp-mirror.googlecode.com/svn/trunk/";
|
|
UpdaterCfg().svnuser="";
|
|
UpdaterCfg().svnpass="";
|
|
}
|
|
UpdaterCfg().globalsrc=FindGlobalSrc();
|
|
UpdaterCfg().available=false;
|
|
}
|
|
|
|
String GetSrcVersion(const char* dir,String& error){
|
|
String fn=AppendFileName(dir,"uppsrc/ide/version.h");
|
|
String ver=LoadFile(fn);
|
|
if(ver.IsVoid()){
|
|
error="Can't read file "+fn;
|
|
}else{
|
|
ver=ver.Mid(ver.Find("IDE_VERSION")+12);
|
|
ver=ver.Mid(ver.Find('"')+1);
|
|
ver=ver.Left(ver.Find('"'));
|
|
}
|
|
LLOG("GetSrcVersion("<<dir<<") = "<<ver);
|
|
return ver;
|
|
}
|
|
|
|
String GetSvnVersion(const String& server,bool verbose,String& error){
|
|
String ver;
|
|
LocalProcess p("svn info "+server);
|
|
if(verbose){
|
|
Progress pi;
|
|
pi.SetText("Checking revision at "+server);
|
|
while(p.IsRunning()){
|
|
if(pi.Canceled()){
|
|
p.Detach(); // p.Kill() would be better, but it hangs...
|
|
error="CANCEL";
|
|
return String::GetVoid();
|
|
}
|
|
pi.Step();
|
|
Sleep(50);
|
|
}
|
|
pi.Close();
|
|
}else{
|
|
while(p.IsRunning()){Ctrl::GuiSleep(1000);}
|
|
}
|
|
int exitcode=p.GetExitCode();
|
|
if(exitcode){
|
|
error="SVN command 'svn info "+server+"' failed with exit code "+AsString(exitcode)+"&Output:&[l150 "+DeQtf(p.Get());
|
|
LDUMP(error);
|
|
return String::GetVoid();
|
|
}
|
|
ver=p.Get();
|
|
ver=ver.Mid(ver.Find("Revision: ")+10);
|
|
LLOG("GetSvnVersion("<<server<<") = "<<IntStr(ScanInt(ver)));
|
|
return IntStr(ScanInt(ver));
|
|
}
|
|
|
|
String FindGlobalSrc(){
|
|
#ifdef PLATFORM_POSIX
|
|
static const char* dirs[]={"/usr/share/upp","/usr/local/share/upp","/usr/local/lib/upp","/usr/lib/upp"};
|
|
int n=4;
|
|
#else
|
|
static const char* dirs[]={}; // Program Files?
|
|
int n=0;
|
|
#endif
|
|
for(int i=0;i<n;i++){
|
|
if(DirectoryExists(dirs[i])) return dirs[i];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
SourceUpdater::SourceUpdater(){
|
|
CtrlLayout(*this,"Updates available");
|
|
ignore<<THISBACK(Ignore);
|
|
skip<<=THISBACK(Close);
|
|
update<<=THISBACK(DoUpdate);
|
|
update.SetFocus();
|
|
//Icon(IdeImg::Package(), IdeImg::PackageLarge());
|
|
}
|
|
|
|
bool SourceUpdater::NeedsUpdate(bool verbose){
|
|
String where;
|
|
LLOG("checking for updates");
|
|
switch(UpdaterCfg().method){
|
|
case 0:{
|
|
//copy in /home
|
|
local=GetSrcVersion(UpdaterCfg().localsrc,error);
|
|
global=GetSrcVersion(UpdaterCfg().globalsrc,error);
|
|
where="in "+UpdaterCfg().globalsrc+" (updated by your package manager)";
|
|
break;
|
|
}
|
|
case 2:{
|
|
//svn repo
|
|
switch(UpdaterCfg().sync){
|
|
case 0:{
|
|
//always newest
|
|
global=GetSvnVersion(UpdaterCfg().svnserver,verbose,error);
|
|
break;
|
|
}
|
|
case 1:{
|
|
//sync with the version of theide
|
|
global=IDE_VERSION;
|
|
break;
|
|
}
|
|
default: return false;
|
|
}
|
|
where="in SVN repository ("+DeQtf(UpdaterCfg().svnserver)+")";
|
|
local=GetSvnVersion(UpdaterCfg().localsrc,false,error);
|
|
break;
|
|
}
|
|
default: return false;
|
|
}
|
|
LLOG("NeedsUpdate: local="<<local<<", global="<<global);
|
|
|
|
|
|
if(ScanInt(global)<=UpdaterCfg().ignored || global.IsVoid() || local.IsVoid())
|
|
return false;
|
|
text<<="[ [ [/ Newer version of U`+`+ sources is available.]&][ &]"
|
|
"[ {{5000:5000FNGN@N; [ [1 Curent local version:]]:: [ [1 "+local+"]]:: [ [1 Will update to:]]:: [ [1 "+global+"]]}}][ &&]"
|
|
"[1# If you choose to update now, your local sources (directory "+DeQtf(UpdaterCfg().localsrc)+") will be compared to the files "+where+". If you modified the files in your local copy, you will be able to choose appropriate actions for each changed file before writing anything on your hard drive.]";
|
|
return UpdaterCfg().available=(ScanInt(local)<ScanInt(global));
|
|
}
|
|
|
|
void SourceUpdater::CheckUpdates(){
|
|
if(UpdaterCfg().method==2) {
|
|
if(UpdaterCfg().sync==1){
|
|
global=IDE_VERSION;
|
|
CheckLocalSvn();
|
|
} else if(UpdaterCfg().sync==0){
|
|
CheckGlobalSvn();
|
|
}
|
|
return;
|
|
}
|
|
//else it is fast enough to run without the callback chain
|
|
UpdaterCfg().last=GetUtcTime();
|
|
StoreAsXMLFile(UpdaterCfg(),"SourceUpdater",ConfigFile("updates.xml"));
|
|
LLOG("running needsupdate");
|
|
if(NeedsUpdate(false))
|
|
WhenUpdateAvailable();
|
|
}
|
|
|
|
void SourceUpdater::CheckLocalSvn(){
|
|
if(pl.IsRunning()) return;
|
|
LLOG("checking local svn");
|
|
pl.Start("svn info "+UpdaterCfg().localsrc);
|
|
SetTimeCallback(-50,THISBACK(CheckLocalSvnFinished),1);
|
|
}
|
|
|
|
void SourceUpdater::CheckLocalSvnFinished(){
|
|
if(pl.IsRunning()) return;
|
|
LLOG("checking local svn finished");
|
|
KillTimeCallback(1);
|
|
int exitcode=pl.GetExitCode();
|
|
if(exitcode){
|
|
error="SVN command 'svn info "+UpdaterCfg().localsrc+"' failed with exit code "+AsString(exitcode)+"&Output:&[l150 "+DeQtf(pl.Get());
|
|
LDUMP(error);
|
|
return;
|
|
}
|
|
local=pl.Get();
|
|
local=local.Mid(local.Find("Revision: ")+10);
|
|
local=IntStr(ScanInt(local));
|
|
text<<="[ [ [/ Newer version of U`+`+ sources is available.]&][ &]"
|
|
"[ {{5000:5000FNGN@N; [ [1 Curent local version:]]:: [ [1 "+local+"]]:: [ [1 Will update to:]]:: [ [1 "+global+"]]}}][ &&]"
|
|
"[1# If you choose to update now, your local sources (directory "+DeQtf(UpdaterCfg().localsrc)+") will be compared to the files in SVN repository ("+DeQtf(UpdaterCfg().svnserver)+"). If you modified the files in your local copy, you will be able to choose appropriate actions for each changed file before writing anything on your hard drive.]";
|
|
UpdaterCfg().available=(ScanInt(local)<ScanInt(global));
|
|
LLOG("Callback chain finished: local="<<local<<", global="<<global);
|
|
UpdaterCfg().last=GetUtcTime();
|
|
StoreAsXMLFile(UpdaterCfg(),"SourceUpdater",ConfigFile("updates.xml"));
|
|
if(UpdaterCfg().available)
|
|
WhenUpdateAvailable();
|
|
}
|
|
|
|
void SourceUpdater::CheckGlobalSvn(){
|
|
if(pg.IsRunning()) return;
|
|
LLOG("checking global svn");
|
|
pg.Start("svn info "+UpdaterCfg().svnserver);
|
|
SetTimeCallback(-500,THISBACK(CheckGlobalSvnFinished),2);
|
|
}
|
|
|
|
void SourceUpdater::CheckGlobalSvnFinished(){
|
|
if(pg.IsRunning()) return;
|
|
LLOG("checking global svn finished");
|
|
KillTimeCallback(2);
|
|
int exitcode=pg.GetExitCode();
|
|
if(exitcode){
|
|
error="SVN command 'svn info "+UpdaterCfg().svnserver+"' failed with exit code "+AsString(exitcode)+"&Output:&[l150 "+DeQtf(pg.Get());
|
|
LLOG(error);
|
|
return;
|
|
}
|
|
global=pg.Get();
|
|
global=global.Mid(global.Find("Revision: ")+10);
|
|
global=IntStr(ScanInt(global));
|
|
if(ScanInt(global)>UpdaterCfg().ignored)
|
|
CheckLocalSvn();
|
|
}
|
|
|
|
void SourceUpdater::DoUpdate(){
|
|
Close();Hide();
|
|
LLOG("DoUpdate");
|
|
switch(UpdaterCfg().method){
|
|
case 0: {
|
|
//copy in /home
|
|
LocalSync ls;
|
|
if(ls.Execute()==IDOK){
|
|
ls.Perform();
|
|
//DeleteFile(ConfigFile("md5sums"));
|
|
FileCopy(AppendFileName(UpdaterCfg().globalsrc,"uppsrc/ide/version.h"),AppendFileName(UpdaterCfg().localsrc,"uppsrc/ide/version.h"));
|
|
}
|
|
break;
|
|
}
|
|
case 2: {
|
|
//svn repository
|
|
SaveFile(AppendFileName(UpdaterCfg().localsrc,"uppsrc/ide/version.h"),"#define IDE_VERSION \"\"\n");
|
|
SvnSync ss;
|
|
ss.Dir(UpdaterCfg().localsrc,UpdaterCfg().svnreadonly);
|
|
if(UpdaterCfg().sync==1){
|
|
ss.FixRevision(UpdaterCfg().localsrc,ScanInt(global));
|
|
}
|
|
ss.DoSync();
|
|
SaveFile(AppendFileName(UpdaterCfg().localsrc,"uppsrc/ide/version.h"),"#define IDE_VERSION \""+global+"\"\n");
|
|
break;
|
|
}
|
|
default: return;
|
|
}
|
|
UpdaterCfg().available=(ScanInt(global)>ScanInt(GetSrcVersion(UpdaterCfg().localsrc,error)));
|
|
}
|
|
|
|
void SourceUpdater::Ignore(){
|
|
UpdaterCfg().ignored=ScanInt(global);
|
|
UpdaterCfg().available=false;
|
|
Close();
|
|
}
|