tex2lyx: Run configure.py if needed (bug #8539)

Since tex2lyx reads some LyX config files it needs to run configure.py if
they do not exist or are out of date.
This commit is contained in:
Georg Baum 2014-12-29 23:46:25 +01:00
parent c1c439b94d
commit b0361fb3c5
7 changed files with 84 additions and 65 deletions

View File

@ -60,8 +60,6 @@
#include "support/Messages.h" #include "support/Messages.h"
#include "support/os.h" #include "support/os.h"
#include "support/Package.h" #include "support/Package.h"
#include "support/PathChanger.h"
#include "support/Systemcall.h"
#include "support/bind.h" #include "support/bind.h"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
@ -127,18 +125,6 @@ void showFileError(string const & error)
"Please check your installation."), from_utf8(error))); "Please check your installation."), from_utf8(error)));
} }
void reconfigureUserLyXDir()
{
string const configure_command = package().configure_command();
lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
PathChanger p(package().user_support());
Systemcall one;
one.startscript(Systemcall::Wait, configure_command);
lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
}
} // namespace anon } // namespace anon
/// The main application class private implementation. /// The main application class private implementation.
@ -724,7 +710,7 @@ namespace {
} }
} }
} }
void cleanDuplicateEnvVars() void cleanDuplicateEnvVars()
{ {
std::set<std::string> seen; std::set<std::string> seen;
@ -825,11 +811,11 @@ bool LyX::init()
// Check that user LyX directory is ok. // Check that user LyX directory is ok.
{ {
string const lock_file = package().user_support().absFileName() + ".lyx_configure_lock"; string const lock_file = package().getConfigureLockName();
int fd = fileLock(lock_file.c_str()); int fd = fileLock(lock_file.c_str());
if (queryUserLyXDir(package().explicit_user_support())) { if (queryUserLyXDir(package().explicit_user_support())) {
reconfigureUserLyXDir(); package().reconfigureUserLyXDir("");
} }
fileUnlock(fd, lock_file.c_str()); fileUnlock(fd, lock_file.c_str());
} }
@ -956,27 +942,6 @@ void emergencyCleanup()
} }
// return true if file does not exist or is older than configure.py.
static bool needsUpdate(string const & file)
{
// We cannot initialize configure_script directly because the package
// is not initialized yet when static objects are constructed.
static FileName configure_script;
static bool firstrun = true;
if (firstrun) {
configure_script =
FileName(addName(package().system_support().absFileName(),
"configure.py"));
firstrun = false;
}
FileName absfile =
FileName(addName(package().user_support().absFileName(), file));
return !absfile.exists()
|| configure_script.lastModified() > absfile.lastModified();
}
bool LyX::queryUserLyXDir(bool explicit_userdir) bool LyX::queryUserLyXDir(bool explicit_userdir)
{ {
// Does user directory exist? // Does user directory exist?
@ -984,10 +949,10 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
if (sup.exists() && sup.isDirectory()) { if (sup.exists() && sup.isDirectory()) {
first_start = false; first_start = false;
return needsUpdate("lyxrc.defaults") return configFileNeedsUpdate("lyxrc.defaults")
|| needsUpdate("lyxmodules.lst") || configFileNeedsUpdate("lyxmodules.lst")
|| needsUpdate("textclass.lst") || configFileNeedsUpdate("textclass.lst")
|| needsUpdate("packages.lst"); || configFileNeedsUpdate("packages.lst");
} }
first_start = !explicit_userdir; first_start = !explicit_userdir;

View File

@ -72,8 +72,6 @@
#include "support/Messages.h" #include "support/Messages.h"
#include "support/os.h" #include "support/os.h"
#include "support/Package.h" #include "support/Package.h"
#include "support/PathChanger.h"
#include "support/Systemcall.h"
#include "support/TempFile.h" #include "support/TempFile.h"
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@ -1065,8 +1063,8 @@ double GuiApplication::pixelRatio() const
return 1.0; return 1.0;
#endif #endif
} }
void GuiApplication::clearSession() void GuiApplication::clearSession()
{ {
QSettings settings; QSettings settings;
@ -1460,18 +1458,16 @@ void GuiApplication::reconfigure(string const & option)
current_view_->message(_("Running configure...")); current_view_->message(_("Running configure..."));
// Run configure in user lyx directory // Run configure in user lyx directory
PathChanger p(package().user_support()); string const lock_file = package().getConfigureLockName();
string configure_command = package().configure_command(); int fd = fileLock(lock_file.c_str());
configure_command += option; int const ret = package().reconfigureUserLyXDir(option);
Systemcall one;
int const ret = one.startscript(Systemcall::Wait, configure_command);
p.pop();
// emit message signal. // emit message signal.
if (current_view_) if (current_view_)
current_view_->message(_("Reloading configuration...")); current_view_->message(_("Reloading configuration..."));
lyxrc.read(libFileSearch(QString(), "lyxrc.defaults"), false); lyxrc.read(libFileSearch(QString(), "lyxrc.defaults"), false);
// Re-read packages.lst // Re-read packages.lst
LaTeXPackages::getAvailable(); LaTeXPackages::getAvailable();
fileUnlock(fd, lock_file.c_str());
if (ret) if (ret)
Alert::information(_("System reconfiguration failed"), Alert::information(_("System reconfiguration failed"),
@ -1713,14 +1709,14 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
// If the request comes from the minibuffer, then we can't reset // If the request comes from the minibuffer, then we can't reset
// the GUI, since that would destory the minibuffer itself and // the GUI, since that would destory the minibuffer itself and
// cause a crash, since we are currently in one of the methods of // cause a crash, since we are currently in one of the methods of
// GuiCommandBuffer. See bug #8540. // GuiCommandBuffer. See bug #8540.
if (cmd.origin() != FuncRequest::COMMANDBUFFER) if (cmd.origin() != FuncRequest::COMMANDBUFFER)
resetGui(); resetGui();
// else // else
// FIXME Unfortunately, that leaves a bug here, since we cannot // FIXME Unfortunately, that leaves a bug here, since we cannot
// reset the GUI in this case. If the changes to lyxrc affected the // reset the GUI in this case. If the changes to lyxrc affected the
// UI, then, nothing would happen. This seems fairly unlikely, but // UI, then, nothing would happen. This seems fairly unlikely, but
// it definitely is a bug. // it definitely is a bug.
break; break;
@ -1933,9 +1929,9 @@ void GuiApplication::dispatch(FuncRequest const & cmd, DispatchResult & dr)
istringstream ss(argument); istringstream ss(argument);
Lexer lex; Lexer lex;
lex.setStream(ss); lex.setStream(ss);
// See #9236 // See #9236
// We need to make sure that, after we recreat the DocumentClass, // We need to make sure that, after we recreat the DocumentClass,
// which we do in readHeader, we apply it to the document itself. // which we do in readHeader, we apply it to the document itself.
DocumentClassConstPtr olddc = defaults.params().documentClassPtr(); DocumentClassConstPtr olddc = defaults.params().documentClassPtr();
int const unknown_tokens = defaults.readHeader(lex); int const unknown_tokens = defaults.readHeader(lex);

View File

@ -21,12 +21,15 @@
#include "support/lassert.h" #include "support/lassert.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/os.h" #include "support/os.h"
#include "support/PathChanger.h"
#include "support/Systemcall.h"
#if defined (USE_WINDOWS_PACKAGING) #if defined (USE_WINDOWS_PACKAGING)
# include "support/os_win32.h" # include "support/os_win32.h"
#endif #endif
#include <iostream>
#include <list> #include <list>
#if !defined (USE_WINDOWS_PACKAGING) && \ #if !defined (USE_WINDOWS_PACKAGING) && \
@ -151,7 +154,8 @@ Package::Package(string const & command_line_arg0,
<< "</package>\n"); << "</package>\n");
} }
std::string const & Package::configure_command() const
int Package::reconfigureUserLyXDir(string const & option) const
{ {
if (configure_command_.empty()) { if (configure_command_.empty()) {
FileName const configure_script(addName(system_support().absFileName(), "configure.py")); FileName const configure_script(addName(system_support().absFileName(), "configure.py"));
@ -160,7 +164,19 @@ std::string const & Package::configure_command() const
with_version_suffix() + " --binary-dir=" + with_version_suffix() + " --binary-dir=" +
quoteName(FileName(binary_dir().absFileName()).toFilesystemEncoding()); quoteName(FileName(binary_dir().absFileName()).toFilesystemEncoding());
} }
return configure_command_;
lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
PathChanger p(user_support());
Systemcall one;
int const ret = one.startscript(Systemcall::Wait, configure_command_ + option);
lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
return ret;
}
string Package::getConfigureLockName() const
{
return user_support().absFileName() + ".lyx_configure_lock";
} }

View File

@ -134,11 +134,11 @@ public:
*/ */
static FileName const & get_home_dir(); static FileName const & get_home_dir();
/** Command to run the configure script. /// Run configure.py
* Caution: This is "ready-to-run", i.e. in the locale encoding, not int reconfigureUserLyXDir(std::string const & option) const;
* utf8.
*/ ///
std::string const & configure_command() const; std::string getConfigureLockName() const;
private: private:
FileName binary_dir_; FileName binary_dir_;
@ -151,6 +151,10 @@ private:
mutable FileName document_dir_; mutable FileName document_dir_;
mutable FileName temp_dir_; mutable FileName temp_dir_;
FileName system_temp_dir_; FileName system_temp_dir_;
/** Command to run the configure script.
* Caution: This is "ready-to-run", i.e. in the locale encoding, not
* utf8.
*/
mutable std::string configure_command_; mutable std::string configure_command_;
bool explicit_user_support_dir_; bool explicit_user_support_dir_;
bool in_build_dir_; bool in_build_dir_;

View File

@ -745,7 +745,7 @@ string const replaceCurdirPath(string const & path, string const & pathlist)
} }
if (i != string::npos) { if (i != string::npos) {
newpathlist += sep; newpathlist += sep;
// Stop here if the last element is empty // Stop here if the last element is empty
if (++i == oldpathlist.length()) if (++i == oldpathlist.length())
break; break;
} }
@ -1172,6 +1172,27 @@ bool prefs2prefs(FileName const & filename, FileName const & tempfile, bool lfun
return true; return true;
} }
bool configFileNeedsUpdate(string const & file)
{
// We cannot initialize configure_script directly because the package
// is not initialized yet when static objects are constructed.
static FileName configure_script;
static bool firstrun = true;
if (firstrun) {
configure_script =
FileName(addName(package().system_support().absFileName(),
"configure.py"));
firstrun = false;
}
FileName absfile =
FileName(addName(package().user_support().absFileName(), file));
return !absfile.exists()
|| configure_script.lastModified() > absfile.lastModified();
}
int fileLock(const char * lock_file) int fileLock(const char * lock_file)
{ {
int fd = -1; int fd = -1;

View File

@ -300,6 +300,9 @@ int compare_timestamps(FileName const & file1, FileName const & file2);
bool prefs2prefs(FileName const & filename, FileName const & tempfile, bool prefs2prefs(FileName const & filename, FileName const & tempfile,
bool lfuns); bool lfuns);
/// Does file \p file need to be updated by configure.py?
bool configFileNeedsUpdate(std::string const & file);
typedef std::pair<int, std::string> cmd_ret; typedef std::pair<int, std::string> cmd_ret;
cmd_ret const runCommand(std::string const & cmd); cmd_ret const runCommand(std::string const & cmd);

View File

@ -996,6 +996,20 @@ int main(int argc, char * argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Check that user LyX directory is ok.
FileName const sup = package().user_support();
if (sup.exists() && sup.isDirectory()) {
string const lock_file = package().getConfigureLockName();
int fd = fileLock(lock_file.c_str());
if (configFileNeedsUpdate("lyxrc.defaults") ||
configFileNeedsUpdate("lyxmodules.lst") ||
configFileNeedsUpdate("textclass.lst") ||
configFileNeedsUpdate("packages.lst"))
package().reconfigureUserLyXDir("");
fileUnlock(fd, lock_file.c_str());
} else
error_message("User directory does not exist.");
// Now every known option is parsed. Look for input and output // Now every known option is parsed. Look for input and output
// file name (the latter is optional). // file name (the latter is optional).
string infilename = internal_path(os::utf8_argv(1)); string infilename = internal_path(os::utf8_argv(1));