Go to the documentation of this file.
22 struct pugi_xml_document;
23 static constexpr
int recentMax = 128;
28 std::ostream* m_stream;
31 class NullBuffer :
public std::streambuf {
33 int overflow(
int c)
override {
return c; }
35 NullBuffer m_null_buffer;
36 mutable std::ostream m_null{&m_null_buffer};
37 std::vector<std::string> m_preambles;
43 std::vector<std::string> preambles = {})
44 : m_stream(&
stream), m_level(
static_cast<int>(
level)), m_preambles(std::move(preambles)) {}
46 : m_stream(source.m_stream), m_level(source.m_level), m_preambles(source.m_preambles) {}
48 : m_stream(std::move(source.m_stream)), m_level(std::move(source.m_level)),
49 m_preambles(std::move(source.m_preambles)) {}
51 m_stream = source.m_stream;
52 m_level = source.m_level;
53 m_preambles = source.m_preambles;
57 m_stream = source.m_stream;
58 m_level = source.m_level;
59 m_preambles = std::move(source.m_preambles);
63 std::ostream&
stream()
const {
return *m_stream; }
65 auto&
stream =
level > m_level ? m_null : *m_stream;
69 stream << message << std::endl;
73 return ((*
this)(
static_cast<int>(
level), message));
77 std::ostream&
warn(
const std::string& message =
"")
const {
return ((*
this)(
Levels::WARNING, message)); }
78 std::ostream&
error(
const std::string& message =
"")
const {
return ((*
this)(
Levels::ERROR, message)); }
79 int level()
const {
return m_level; }
85 template <
typename Arg>
93 std::string m_project_suffix;
94 std::filesystem::path m_filename;
95 std::vector<std::filesystem::path> m_reserved_files =
97 std::vector<std::filesystem::path>{sjef::Project::s_propertyFile};
98 std::unique_ptr<pugi_xml_document> m_properties;
100 std::map<std::string, Backend> m_backends;
102 std::unique_ptr<pugi_xml_document> m_backend_doc;
103 mutable std::shared_ptr<remote_server> m_remote_server;
104 mutable std::chrono::milliseconds m_status_lifetime = std::chrono::milliseconds(0);
105 mutable std::chrono::time_point<std::chrono::steady_clock> m_status_last = std::chrono::steady_clock::now();
106 mutable std::thread m_backend_watcher;
109 struct backend_watcher_flag_container {
110 std::atomic_flag shutdown_flag;
111 std::mutex m_property_set_mutex;
113 mutable backend_watcher_flag_container m_unmovables;
114 std::unique_ptr<Project> m_backend_watcher_instance;
115 const Project* m_master_instance;
116 bool m_master_of_slave;
119 mutable std::mutex m_status_mutex;
120 mutable std::mutex m_remote_server_mutex;
121 mutable std::mutex m_synchronize_mutex;
122 mutable std::string m_backend;
123 mutable std::string m_xml_cached;
124 std::string remote_server_run(
const std::string& command,
int verbosity = 0,
bool wait =
true)
const;
126 static const std::string s_propertyFile;
128 std::shared_ptr<Locker> m_locker;
148 explicit Project(
const std::filesystem::path&
filename,
bool construct =
true,
const std::string& default_suffix =
"",
149 const mapstringstring_t& suffixes = {{
"inp",
"inp"}, {
"out",
"out"}, {
"xml",
"xml"}},
150 bool monitor =
true,
bool sync =
true,
const Project* masterProject =
nullptr);
168 bool copy(
const std::filesystem::path& destination_filename,
bool force =
false,
bool keep_hash =
false,
bool slave =
false,
int keep_run_directories=std::numeric_limits<int>::max());
176 bool move(
const std::filesystem::path& destination_filename,
bool force =
false);
181 static void erase(
const std::filesystem::path&
filename,
const std::string& default_suffix =
"");
189 bool import_file(
const std::filesystem::path& file,
bool overwrite =
false);
190 bool import_file(
const std::vector<std::string>& files,
bool overwrite =
false) {
192 for (
const auto& file : files)
202 bool export_file(
const std::filesystem::path& file,
bool overwrite =
false);
203 bool export_file(
const std::vector<std::string>& files,
bool overwrite =
false) {
205 for (
const auto& file : files)
218 bool synchronize(
int verbosity = 0,
bool nostatus =
false,
bool force =
false)
const;
226 std::vector<std::string> preambles = {
"sjef:: Error: ",
"sjef:: Warning: ",
"sjef:: Note:"}) {
227 m_warn =
Logger{stream, level, std::move(preambles)};
229 void set_verbosity(
int verbosity, std::ostream& stream = std::cout) { m_trace =
Logger(stream, verbosity); }
240 bool run(
int verbosity = 0,
bool force =
false,
bool wait =
false);
241 bool run(
const std::string&
name,
int verbosity = 0,
bool force =
false,
bool wait =
false) {
243 return run(verbosity, force,
wait);
274 void wait(
unsigned int maximum_microseconds = 10000)
const;
295 void rewrite_input_file(
const std::string& input_file_name,
const std::string& old_name);
314 std::string
xml(
int run = 0,
bool sync =
true)
const;
328 std::string
file_contents(
const std::string& suffix =
"",
const std::string&
name =
"",
int run = 0,
329 bool sync =
true)
const;
338 void clean(
bool oldOutput =
true,
bool output =
false,
bool unused =
false,
int keep_run_directories=0);
344 void property_set(
const std::string& property,
const std::string& value);
355 std::string
property_get(
const std::string& property)
const;
385 std::filesystem::path
filename(std::string suffix =
"",
const std::string&
name =
"",
int run = -1)
const;
429 std::string
name()
const;
444 static std::string
recent(
const std::string& suffix,
int number = 1);
445 std::string
recent(
int number = 1)
const;
454 void change_backend(std::string backend = std::string{
""},
bool force =
false);
456 std::map<std::string, Backend>&
backends() {
return m_backends; }
459 Backend default_backend();
462 void throw_if_backend_invalid(std::string backend =
"")
const;
463 std::string get_project_suffix(
const std::filesystem::path&
filename,
const std::string& default_suffix)
const;
464 static void recent_edit(
const std::filesystem::path& add,
const std::filesystem::path& remove =
"");
465 mutable std::filesystem::file_time_type m_property_file_modification_time;
466 mutable std::map<std::string, std::filesystem::file_time_type, std::less<>> m_input_file_modification_time;
467 std::set<std::string, std::less<>> m_run_directory_ignore;
468 void property_delete_locked(
const std::string& property);
469 void check_property_file_locked()
const;
470 void check_property_file()
const;
471 void save_property_file_locked()
const;
472 void save_property_file()
const;
473 void load_property_file_locked()
const;
474 bool properties_last_written_by_me(
bool removeFile =
false)
const;
485 std::string cache(
const Backend& backend)
const;
486 void force_file_names(
const std::string& oldname);
487 static void backend_watcher(
sjef::Project& project_,
int min_wait_milliseconds,
int max_wait_milliseconds = 0,
488 int poll_milliseconds = 1);
489 void shutdown_backend_watcher();
497 std::string referenced_file_contents(
const std::string& line)
const;
525 std::string
backend_get(
const std::string& backend,
const std::string& key)
const;
562 if (p.find(
"!") == std::string::npos)
564 return p.substr(0, p.find(
"!"));
575 if (ps.count(
name) == 0)
588 if (ps.count(
name) == 0)
635 void take_run_files(
int run = 0,
const std::string& fromname =
"",
const std::string& toname =
"")
const;
656 pugi::xpath_node_set
select_nodes(
const std::string& xpath_query,
int run = 0)
const;
665 std::vector<std::string>
xpath_search(
const std::string& xpath_query,
const std::string& attribute =
"",
693 std::filesystem::path
expand_path(
const std::filesystem::path& path,
const std::string& suffix =
"");
709 std::string
version() noexcept;
712 using std::runtime_error::runtime_error;
717 #endif // SJEF_SJEF_H
std::filesystem::path propertyFile() const
std::map< std::string, std::string > mapstringstring_t
Definition: sjef.h:25
std::string xmlRepair(const std::string &source, const mapstringstring_t &injections={})
Repair an xml dataset by completing any open tags.
void property_delete(const std::string &property)
Remove a variable.
size_t project_hash()
Return a globally-unique hash to identify the project. The hash is generated on first call to this fu...
void take_run_files(int run=0, const std::string &fromname="", const std::string &toname="") const
Copy files from a run directory to the main project.
std::ostream & warn(const std::string &message="") const
Definition: sjef.h:77
@ running
Definition: sjef.h:24
run_list_t run_list() const
Logger(std::ostream &stream=std::cout, const Levels level=Levels::ERROR, std::vector< std::string > preambles={})
Definition: sjef.h:42
Logger(Logger &&source) noexcept
Definition: sjef.h:47
Logger(const Logger &source)
Definition: sjef.h:45
size_t input_hash() const
Construct a hash that is unique to the contents of the input file and anything it references.
std::filesystem::path filename(std::string suffix="", const std::string &name="", int run=-1) const
Get the file name of the bundle, or a primary file of particular type, or a general file in the bundl...
@ waiting
Definition: sjef.h:24
Levels
Definition: sjef.h:40
void set_level(Levels level)
Definition: sjef.h:81
std::vector< std::string > property_names() const
Get the names of all assigned properties.
static void erase(const std::filesystem::path &filename, const std::string &default_suffix="")
Erase a project from the file system, and remove it from the recent projects file.
std::filesystem::path expand_path(const std::filesystem::path &path, const std::string &suffix="")
Edit a file path name.
std::string backend_parameter_default(const std::string &backend, const std::string &name) const
Return the default value associated with a backend run parameter.
Definition: sjef.h:586
void rewrite_input_file(const std::string &input_file_name, const std::string &old_name)
void set_stream(std::ostream &stream)
Definition: sjef.h:82
sjef::status status(int verbosity=0, bool cached=true) const
Obtain the status of the job started by run()
bool import_file(const std::vector< std::string > &files, bool overwrite=false)
Definition: sjef.h:190
std::ostream & stream() const
Definition: sjef.h:63
void set_current_run(unsigned int run=0)
Set the focussed run directory.
void change_backend(std::string backend=std::string{""}, bool force=false)
Change the active backend.
std::string backend_get(const std::string &backend, const std::string &key) const
Obtain the value of a field in a backend.
bool check_backend(const std::string &name) const
Check whether the specification of a backend is valid.
void clean(bool oldOutput=true, bool output=false, bool unused=false, int keep_run_directories=0)
Remove potentially unwanted files from the project.
std::vector< std::string > xpath_search(const std::string &xpath_query, const std::string &attribute="", int run=0) const
Simple XPath search on the xml document. For each matching node found, return a string that contains ...
void add_backend(const std::string &name, const mapstringstring_t &fields)
Introduce a new backend to the project and to the user's global backend configuration for all project...
status
Definition: sjef.h:24
std::ostream & detail(const std::string &message="") const
Definition: sjef.h:75
A thread-safe class for an inter-thread/inter-process lock. The lock mechanism is based on a locked f...
Definition: Locker.h:28
bool export_file(const std::filesystem::path &file, bool overwrite=false)
Export one or more files from the project.
void custom_initialisation()
Perform any project initialisation specific to the project suffix.
void property_set(const std::string &property, const std::string &value)
Set a property.
std::string input_from_output(bool sync=true) const
If possible, construct the input embedded in the output file.
std::string backend_parameter_expand(const std::string &backend, std::string templ="") const
Perform parameter substitution for a backend run_command template.
bool move(const std::filesystem::path &destination_filename, bool force=false)
Move the project to another location.
void kill()
Kill the job started by run()
void wait(unsigned int maximum_microseconds=10000) const
Wait unconditionally for status() to return neither 'waiting' nor 'running'.
std::ostream & operator()(int level, const std::string &message="") const
Definition: sjef.h:64
std::ostream & operator()(const Levels level, const std::string &message="") const
Definition: sjef.h:72
std::vector< std::string > backend_names() const
Get the names of all the backend objects associated with the object.
bool check_all_backends() const
Check the specification of all backends for validity.
@ completed
Definition: sjef.h:24
void set_warnings(const Logger::Levels level=Logger::Levels::WARNING, std::ostream &stream=std::cerr, std::vector< std::string > preambles={"sjef:: Error: ", "sjef:: Warning: ", "sjef:: Note:"})
Set the warning/error diagnostic level and destination.
Definition: sjef.h:225
int run_verify(int run) const
Check a run exists, and resolve most recent.
@ unknown
Definition: sjef.h:24
bool run(int verbosity=0, bool force=false, bool wait=false)
Start a sjef job.
@ unevaluated
Definition: sjef.h:24
bool export_file(const std::vector< std::string > &files, bool overwrite=false)
Definition: sjef.h:203
std::string file_contents(const std::string &suffix="", const std::string &name="", int run=0, bool sync=true) const
Obtain the contents of a project file.
int run_directory_next() const
Obtain the sequence number of the next run directory to be created.
std::ostream & operator<<(const Logger &l, Arg arg)
Definition: sjef.h:86
@ killed
Definition: sjef.h:24
std::string status_message(int verbosity=0) const
void set_verbosity(int verbosity, std::ostream &stream=std::cout)
Definition: sjef.h:229
static std::string recent(const std::string &suffix, int number=1)
Look for a project by rank in the user-global recent project list.
bool import_file(const std::filesystem::path &file, bool overwrite=false)
Import one or more files into the project. In the case of a .xml output file, if the corresponding in...
mapstringstring_t backend_parameters(const std::string &backend, bool doc=false) const
Get all of the parameters referenced in the run_command of a backend.
bool copy(const std::filesystem::path &destination_filename, bool force=false, bool keep_hash=false, bool slave=false, int keep_run_directories=std::numeric_limits< int >::max())
Copy the project to another location.
Project(const std::filesystem::path &filename, bool construct=true, const std::string &default_suffix="", const mapstringstring_t &suffixes={{"inp", "inp"}, {"out", "out"}, {"xml", "xml"}}, bool monitor=true, bool sync=true, const Project *masterProject=nullptr)
Construct, or attach to, a Molpro project bundle.
std::string property_get(const std::string &property) const
Get the value of a property.
bool run_needed(int verbosity=0) const
Check whether the job output is believed to be out of date with respect to the input and any other fi...
void set_level(int level)
Definition: sjef.h:80
int run_directory_new()
Create a new run directory. Also copy into it the input file, and any of its dependencies.
unsigned int current_run() const
Get the focussed run directory.
pugi::xpath_node_set select_nodes(const std::string &xpath_query, int run=0) const
General XPath search on the xml document. Needs the pugixml library to parse the result.
std::string version() noexcept
Report the software version.
static const std::vector< std::string > suffix_keys
Definition: sjef.h:500
Logger & operator=(const Logger &source)
Definition: sjef.h:50
std::ostream & notify(const std::string &message="") const
Definition: sjef.h:76
std::set< int, std::greater< int > > run_list_t
Obtain the list of run numbers in reverse order, ie the most recent first.
Definition: sjef.h:406
std::map< std::string, Backend > & backends()
Definition: sjef.h:456
std::filesystem::path run_directory(int run=0) const
Obtain the path of a run directory.
void backend_parameter_set(const std::string &backend, const std::string &name, const std::string &value)
Definition: sjef.h:552
std::ostream & error(const std::string &message="") const
Definition: sjef.h:78
bool synchronize(int verbosity=0, bool nostatus=false, bool force=false) const
Synchronize the project with a cached copy belonging to a backend. name.inp, name....
Logger(std::ostream &stream, int level)
Definition: sjef.h:41
std::string backend_parameter_documentation(const std::string &backend, const std::string &name) const
Return the documentation associated with a backend run parameter.
Definition: sjef.h:573
Logger & operator=(Logger &&source) noexcept
Definition: sjef.h:56
void backend_parameter_delete(const std::string &backend, const std::string &name)
Definition: sjef.h:556
bool check_backends(const std::string &suffix)
Check whether a backend specification file is valid. Only the top-level structure of the file is chec...
void ensure_remote_server() const
bool run(const std::string &name, int verbosity=0, bool force=false, bool wait=false)
Definition: sjef.h:241
void delete_backend(const std::string &name)
Remove a backend from the project and from the user's global backend configuration for all projects o...
const std::string backend_cache() const
Get the location of the backend cache.
std::string backend_parameter_get(const std::string &backend, const std::string &name) const
Definition: sjef.h:560
void run_delete(int run)
Delete a run directory.
void custom_run_preface()
Before launching a job, perform any required actions specific to the project suffix.
static int recent_find(const std::string &suffix, const std::filesystem::path &filename)
Look for a project by name in the user-global recent project list.
int level() const
Definition: sjef.h:79
std::string xml(int run=0, bool sync=true) const
Get the xml output, completing any open tags if necessary.