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