CASM  1.1.0
A Clusters Approach to Statistical Mechanics
files.cc
Go to the documentation of this file.
1 #include <cstring>
2 
5 #include "casm/casm_io/Log.hh"
7 #include "casm/misc/algorithm.hh"
8 
9 namespace CASM {
10 
11 namespace Completer {
13 
14 const std::vector<std::string> &FilesOption::calc_vec() const {
15  return m_calc_vec;
16 }
17 
18 const std::string &FilesOption::settings_str() const { return m_settings_str; }
19 
24 
25  m_desc.add_options()(
26  "settings",
27  po::value<std::string>(&m_settings_str)->default_value("curr"),
28  "Which settings to include. "
29  "One of: 'curr' (default), 'all'.")
30 
31  ("calc", po::value<std::vector<std::string> >(&m_calc_vec)->multitoken(),
32  "Which calculation files to include. "
33  "May be zero (default) or more of: 'settings', 'status', 'all'.") // TODO:
34  // Include
35  // these
36  // in
37  // ArgHandler
38 
39  ("relative,R", "Print relative path from project root directory.");
40 }
41 } // namespace Completer
42 
43 // ///////////////////////////////////////
44 // 'files' function for casm
45 // (add an 'if-else' statement in casm.cpp to call this)
46 
47 int files_command(const CommandArgs &args) {
48  po::variables_map vm;
49  fs::path out_path;
50  std::string settings;
51  std::vector<std::string>
52  calc; // These variable names are bad and you should feel bad
53  bool gz_flag;
54 
56  Completer::FilesOption files_opt;
57 
58  try {
59  po::store(
60  po::parse_command_line(args.argc(), args.argv(), files_opt.desc()),
61  vm); // can throw
62 
63  if (!vm.count("help")) {
64  std::vector<std::string> allowed;
65 
66  allowed = std::vector<std::string>{"", "curr", "all"};
67  if (!contains(allowed, settings)) {
68  err_log() << "Error in 'casm files'. '" << settings
69  << "' is not a valid option to --settings." << std::endl;
70  err_log() << " Valid options are: 'curr', 'all'" << std::endl;
71  return ERR_INVALID_ARG;
72  }
73 
74  allowed = std::vector<std::string>{"settings", "status", "all"};
75  for (auto it = calc.begin(); it != calc.end(); ++it) {
76  if (!contains(allowed, *it)) {
77  err_log() << "Error in 'casm files'. '" << *it
78  << "' is not a valid option to --calc." << std::endl;
79  err_log() << " Valid options are: 'settings', 'status', 'all'"
80  << std::endl;
81  return ERR_INVALID_ARG;
82  }
83  }
84  }
85 
88  if (vm.count("help")) {
89  log() << "\n";
90  log() << files_opt.desc() << std::endl;
91 
92  return 0;
93  }
94 
95  if (vm.count("desc")) {
96  log() << "\n";
97  log() << files_opt.desc() << std::endl;
98 
99  log()
100  << "DESCRIPTION \n"
101  " Enumerate files used by this CASM project\n"
102  " - If --all given, include files from all settings (bset, \n"
103  " calctype, ref, clex, eci). Otherwise only include files\n"
104  " relevant to the current settings.\n"
105  " - If --calc given, include training data files. This option\n"
106  " accepts one or more of: 'settings', 'status', or 'all'.\n"
107  " 'settings': include files from the 'training_data' \n"
108  " settings directories.\n"
109  " 'status': include 'properties.calc.json' and \n"
110  " 'status.json' files.\n"
111  " 'all': include all files in the 'training_data'\n"
112  " directory, recursively.\n\n"
113 
114  " Examples:\n"
115  " casm files\n"
116  " - Prints basic project files for the current settings.\n"
117  " - Prints absolute paths.\n\n"
118 
119  " casm files -R\n"
120  " - Prints basic project files for the current settings.\n"
121  " - Prints relative paths from project root directory.\n\n"
122 
123  " casm files -o absfiles.txt\n"
124  " - Write 'absfiles.txt' with basic project files for \n"
125  " the current settings.\n"
126  " - Prints absolute paths.\n\n"
127 
128  " casm files -R -o relfiles.txt\n"
129  " - Write 'relfiles.txt' with basic project files for \n"
130  " the current settings.\n"
131  " - Prints relative paths from project root directory.\n\n"
132 
133  " tar -czvf proj.tar.gz `casm files -o STDOUT` \n"
134  " tar -czvf proj.tar.gz -T absfiles.txt \n"
135  " - Use tar to create an archive of your CASM project. \n"
136  " - Extract with 'tar -xzvf proj.tar.gz'. \n\n"
137 
138  " rsync -avPR `casm files -R -o STDOUT` destination -n \n"
139  " - Copy project files to the 'destination' directory, \n"
140  " creating sub-directories as necessary. \n"
141  " - **Must run from project root directory** \n"
142  " - Replace 'destination' with '-e ssh "
143  "user@host:destination' \n"
144  " for a remote destination.\n"
145  " - \"-n\" option is for a \"dry-run\". Remove it when ready "
146  "\n"
147  " to do the transfer.\n\n"
148 
149  " rsync -avPR --files-from=relfiles.txt src destination -n \n"
150  " - Copy project files to the 'destination' directory, \n"
151  " creating sub-directories as necessary. \n"
152  " - 'src' is the path to the root directory of the CASM\n"
153  " project you are copying from. \n"
154  " - Replace 'destination' with '-e ssh "
155  "user@host:destination' \n"
156  " for a remote destination.\n"
157  " - \"-n\" option is for a \"dry-run\". Remove it when ready "
158  "\n"
159  " to do the transfer.\n";
160 
161  return 0;
162  }
163 
164  po::notify(vm); // throws on error, so do after help in case
165  // there are any problems
166 
167  out_path = files_opt.output_path();
168  settings = files_opt.settings_str();
169  calc = files_opt.calc_vec();
170  gz_flag = files_opt.gzip_flag();
171 
172  } catch (po::error &e) {
173  err_log() << files_opt.desc() << std::endl;
174  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
175  return ERR_INVALID_ARG;
176  } catch (std::exception &e) {
177  err_log() << files_opt.desc() << std::endl;
178  err_log() << "ERROR: " << e.what() << std::endl << std::endl;
179  return ERR_UNKNOWN;
180  }
181 
182  auto check_gz = [=](fs::path p) {
183  if (p.extension() == ".gz" || p.extension() == ".GZ") {
184  return true;
185  }
186  return false;
187  };
188 
189  if (check_gz(out_path)) {
190  gz_flag = true;
191  }
192 
193  const fs::path &root = args.root;
194  if (root.empty()) {
195  err_log().error("No casm project found");
196  err_log() << std::endl;
197  return ERR_NO_PROJ;
198  }
199 
200  // If '_primclex', use that, else construct PrimClex in 'uniq_primclex'
201  // Then whichever exists, store reference in 'primclex'
202  std::unique_ptr<PrimClex> uniq_primclex;
203  Log &status_log = (out_path.string() == "STDOUT") ? err_log() : log();
204  auto logging = notstd::make_unique<ScopedLogging>(status_log, err_log());
205  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
206  logging.reset();
207 
208  std::vector<fs::path> files;
209  auto result = std::back_inserter(files);
210  FileEnumerator enumerate(primclex, settings == "all", vm.count("relative"));
211 
212  result = enumerate.basic_files(result);
213  result = enumerate.bset_files(result);
214  result = enumerate.reference_files(result);
215  result = enumerate.eci_files(result);
216 
217  bool calc_settings = contains(calc, "settings");
218  bool calc_status = contains(calc, "status");
219  bool calc_all = contains(calc, "all");
220 
221  if (calc_settings && !calc_all) {
222  result = enumerate.calc_settings_files(result);
223  }
224  if (calc_status && !calc_all) {
225  result = enumerate.calc_status_files(result);
226  }
227  if (calc_all) {
228  result = enumerate.all_calc_files(result);
229  }
230 
231  // set output_stream: where the file paths are written
232  std::unique_ptr<std::ostream> uniq_fout;
233  std::ostream &output_stream =
234  make_ostream_if(vm.count("output"), log(), uniq_fout, out_path, gz_flag);
235 
236  for (auto f : files) {
237  output_stream << f.string() << "\n";
238  }
239 
240  return 0;
241 };
242 
243 } // namespace CASM
#define ERR_NO_PROJ
Definition: errors.hh:13
#define ERR_UNKNOWN
Definition: errors.hh:10
#define ERR_INVALID_ARG
Definition: errors.hh:7
int argc() const
Definition: CLIParse.hh:20
char ** argv() const
Definition: CLIParse.hh:22
std::vector< std::string > m_calc_vec
Definition: Handlers.hh:657
const std::string & settings_str() const
Definition: files.cc:18
bool gzip_flag() const
Returns the value assigned for add_gzip_suboption()
Definition: Handlers.cc:372
void initialize() override
Fill in the options descriptions accordingly.
Definition: files.cc:20
const std::vector< std::string > & calc_vec() const
Definition: files.cc:14
const fs::path output_path() const
Returns the path corresponding to add_output_suboption()
Definition: Handlers.cc:370
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:321
void add_help_suboption()
Add a plain –help and –desc suboptions.
Definition: Handlers.cc:561
po::options_description m_desc
Definition: Handlers.hh:260
void add_output_suboption()
Add a –output suboption. Expects to allow "STDOUT" to print to screen.
Definition: Handlers.cc:626
Lists all files in a CASM project, for use with 'casm files' command.
OutputIterator all_calc_files(OutputIterator result)
Enumerate all training data files.
OutputIterator calc_status_files(OutputIterator result)
Enumerate calculation status files.
OutputIterator reference_files(OutputIterator result)
Enumerate reference files.
OutputIterator eci_files(OutputIterator result)
Enumerate eci files.
OutputIterator calc_settings_files(OutputIterator result)
Enumerate calculation settings files.
OutputIterator bset_files(OutputIterator result)
Enumerate bset files.
OutputIterator basic_files(OutputIterator result)
Enumerate all setting independent files.
Definition: Log.hh:48
void error(const std::string &what)
Definition: Log.hh:129
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
std::ostream & make_ostream_if(bool output, std::ostream &sout, std::unique_ptr< std::ostream > &fout, fs::path out_path, bool gzip)
Return a reference to proper std::ostream.
PrimClex & make_primclex_if_not(const CommandArgs &args, std::unique_ptr< PrimClex > &uniq_primclex)
If !_primclex, construct new PrimClex stored in uniq_primclex, then return reference to existing or c...
Main CASM namespace.
Definition: APICommand.hh:8
Log & log()
Definition: Log.hh:424
int files_command(const CommandArgs &args)
Definition: files.cc:47
bool contains(const Container &container, const T &value)
Equivalent to container.end() != std::find(container.begin(), container.end(), value)
Definition: algorithm.hh:83
std::string calc_status(const ConfigType &_config, std::string calctype="")
Status of calculation.
Definition: Calculable.cc:153
Log & err_log()
Definition: Log.hh:426
PrimClex * primclex
Definition: settings.cc:135
Data structure holding basic CASM command info.