CASM
AClustersApproachtoStatisticalMechanics
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules
rm.cc
Go to the documentation of this file.
5 #include "casm/app/AppIO.hh"
8 
10 
11 namespace CASM {
12 
13  namespace Completer {
15 
16  bool RmOption::force() const {
17  return vm().count("force");
18  }
19 
20  bool RmOption::dry_run() const {
21  return vm().count("dry-run");
22  }
23 
29 
30  m_desc.add_options()
31  ("dry-run,n", "Dry run")
32  ("force,f", "Force remove.");
33 
34  return;
35  }
36  }
37 
38  int _rm_configs(const CommandArgs &args, const Completer::RmOption &rm_opt);
39  int _rm_scel(const CommandArgs &args, const Completer::RmOption &rm_opt);
40 
41  // ///////////////////////////////////////
42  // 'rm' function for casm
43 
44  int rm_command(const CommandArgs &args) {
45 
46 
48  Completer::RmOption rm_opt;
49  po::variables_map &vm = rm_opt.vm();
50 
51  bool rm_config = false;
52  bool rm_scel = false;
53 
54  try {
55  po::store(po::parse_command_line(args.argc, args.argv, rm_opt.desc()), vm); // can throw
56 
57  bool call_help = false;
58 
59  // allow --config && --confignames or --scelnames, but not both
60  if(!vm.count("help") && !vm.count("desc")) {
61 
62  rm_config = vm.count("config") + vm.count("confignames");
63  rm_scel = vm.count("scelnames");
64 
65  if(!rm_config && !rm_scel) {
66  args.log << "Error in 'casm rm': At least one of --config, "
67  "--confignames, --scelnames must be given." << std::endl;
68  call_help = true;
69  }
70 
71  if(rm_config + rm_scel > 1) {
72  args.log << "Error in 'casm rm': May not delete multiple types at the same time." << std::endl;
73  call_help = true;
74  }
75  }
76 
79  if(vm.count("help") || call_help) {
80  args.log << "\n";
81  args.log << rm_opt.desc() << std::endl;
82 
83  return 0;
84  }
85 
86  if(vm.count("desc")) {
87  args.log << "\n";
88  args.log << rm_opt.desc() << std::endl;
89  args.log << "DESCRIPTION" << std::endl;
90  args.log << " Remove configuration data and supercells.\n"
91 
92  " Can remove: \n"
93  " - A supercell, including all enumerated configurations \n"
94  " and data (for all calctypes) via --scelnames.\n"
95  " - Calculation data (for the current calctype) for \n"
96  " individual configurations via --config or --confignames.\n\n"
97 
98  " Cannot remove: \n"
99  " - Specific enumerated configuration. The current version \n"
100  " of CASM is restricted to consequitively numbered \n"
101  " configurations in each supercell, so configurations may\n"
102  " only be erased by erasing a supercell.\n\n";
103 
104  return 0;
105  }
106 
107  po::notify(vm); // throws on error, so do after help in case
108  // there are any problems
109 
110  }
111  catch(po::error &e) {
112  args.err_log << "ERROR: " << e.what() << std::endl << std::endl;
113  args.err_log << rm_opt.desc() << std::endl;
114  return ERR_INVALID_ARG;
115  }
116  catch(std::exception &e) {
117  args.err_log << "Unhandled Exception reached the top of main: "
118  << e.what() << ", application will now exit" << std::endl;
119  return ERR_UNKNOWN;
120 
121  }
122 
123  const fs::path &root = args.root;
124  if(root.empty()) {
125  args.err_log.error("No casm project found");
126  args.err_log << std::endl;
127  return ERR_NO_PROJ;
128  }
129 
130  // Only allow erasing one type at a time (check is above to call help):
131  // - configurations: --config / --confignames
132  // - supercells: --scelnames
133  if(rm_config) {
134  return _rm_configs(args, rm_opt);
135  }
136  else if(rm_scel) {
137  return _rm_scel(args, rm_opt);
138  }
139  return ERR_INVALID_ARG;
140  }
141 
142  int _rm_configs(const CommandArgs &args, const Completer::RmOption &rm_opt) {
143 
144  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
145  // Then whichever exists, store reference in 'primclex'
146  std::unique_ptr<PrimClex> uniq_primclex;
147  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
148 
149  // if selection of configurations
150  std::unique_ptr<ConstConfigSelection> selection;
151  if(rm_opt.vm().count("config")) {
152  selection = notstd::make_unique<ConstConfigSelection>(primclex, rm_opt.selection_path());
153  }
154  else if(rm_opt.vm().count("confignames")) {
155  selection = notstd::make_unique<ConstConfigSelection>(primclex, fs::path("NONE"));
156  for(const auto &configname : rm_opt.config_strs()) {
157  selection->set_selected(configname, true);
158  }
159  }
160 
161  if(rm_opt.dry_run()) {
162  args.log << "dry-run...\n\n";
163  }
164 
165  for(auto it = selection->selected_config_begin(); it != selection->selected_config_end(); ++it) {
166  args.log.custom(std::string("Erase ") + it->name() + " data");
167  if(rm_opt.force() && fs::exists(it->calc_dir())) {
168  recurs_rm_files(it->calc_dir(), rm_opt.dry_run(), args.log);
169  }
170  else if(fs::exists(it->calc_dir())) {
171  args.log << "skipping " << it->name() << " data: --force option not given\n";
172  }
173  else {
174  args.log << "skipping " << it->name() << " data: no data\n";
175  }
176  args.log << "\n";
177  }
178 
179  return 0;
180  }
181 
182  int _rm_scel(const CommandArgs &args, const Completer::RmOption &rm_opt) {
183 
184  // If 'args.primclex', use that, else construct PrimClex in 'uniq_primclex'
185  // Then whichever exists, store reference in 'primclex'
186  std::unique_ptr<PrimClex> uniq_primclex;
187  PrimClex &primclex = make_primclex_if_not(args, uniq_primclex);
188 
189  // collect supercells to delete
190  std::set<std::string> scel_to_delete;
191 
192  args.log.custom("Check supercells");
193  for(const auto &scelname : rm_opt.supercell_strs()) {
194  Index index;
195  if(!primclex.contains_supercell(scelname, index)) {
196  args.log << "skipping " << scelname << ": does not exist.\n";
197  continue;
198  }
199 
200  const Supercell &scel = primclex.get_supercell(index);
201 
202  if(!rm_opt.force() && scel.get_config_list().size()) {
203  args.log << "skipping " << scelname << ": has "
204  << scel.get_config_list().size() << " configurations and --force not given.\n";
205  }
206  else {
207  args.log << "will erase " << scelname << "\n";
208  scel_to_delete.insert(scelname);
209  }
210  }
211 
212  args.log << std::endl;
213 
214  // Erase supercells from SCEL and config_list.json
215  if(!scel_to_delete.size()) {
216  args.log << "No supercells to erase\n";
217  }
218  else {
219  for(const auto &scelname : scel_to_delete) {
220  args.log.custom(std::string("Erase ") + scelname);
221  const Supercell &scel = primclex.get_supercell(scelname);
222  recurs_rm_files(scel.get_path(), rm_opt.dry_run(), args.log);
223  args.log << "\n";
224  }
225 
226  if(!rm_opt.dry_run()) {
227  primclex.print_supercells(scel_to_delete);
228  primclex.write_config_list(scel_to_delete);
229  }
230  }
231  return 0;
232 
233  };
234 
235 }
Data structure holding basic CASM command info.
int _rm_scel(const CommandArgs &args, const Completer::RmOption &rm_opt)
Definition: rm.cc:182
void write_config_list(std::set< std::string > scel_to_delete={})
Definition: PrimClex.cc:450
#define ERR_UNKNOWN
void add_scelnames_suboption()
Add a –scelnames suboption.
Definition: Handlers.cc:346
#define ERR_INVALID_ARG
int _rm_configs(const CommandArgs &args, const Completer::RmOption &rm_opt)
Definition: rm.cc:142
int rm_command(const CommandArgs &args)
Definition: rm.cc:44
PrimClex * primclex
Definition: settings.cc:101
void add_help_suboption()
Add a plain –help suboption.
Definition: Handlers.cc:276
ConfigList & get_config_list()
Definition: Supercell.hh:279
Main CASM namespace.
Definition: complete.cpp:8
Represents a supercell of the primitive parent crystal structure.
Definition: Supercell.hh:37
const fs::path & selection_path() const
Returns the string corresponding to add_config_suboption()
Definition: Handlers.cc:168
fs::path get_path() const
Return path to supercell directory.
Definition: Supercell.cc:865
void custom(const std::string &what)
Definition: Log.hh:96
void add_configlist_nodefault_suboption()
Add –config suboption (no default)
Definition: Handlers.cc:258
const po::options_description & desc()
Get the program options, filled with the initialized values.
Definition: Handlers.cc:160
EigenIndex Index
For long integer indexing:
void recurs_rm_files(fs::path p, bool dry_run, Log &log)
Remove files recursively.
po::options_description m_desc
Boost program options. All the derived classes have them, but will fill them up themselves.
Definition: Handlers.hh:126
const std::vector< std::string > & config_strs() const
Returns the names of the supercells for add_configname_suboption(), for when multiple=false.
Definition: Handlers.cc:204
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:52
void add_confignames_suboption()
Add a –confignames suboption.
Definition: Handlers.cc:365
void print_supercells(std::set< std::string > scel_to_delete={}) const
Definition: PrimClex.cc:557
const std::vector< std::string > & supercell_strs() const
Returns the list of the supercells for add_scelnames_suboption()
Definition: Handlers.cc:212
ConfigIO::GenericConfigFormatter< std::string > configname()
Constructs DataFormmaterDictionary containing all Configuration DatumFormatters.
Definition: ConfigIO.cc:340
void initialize() override
Fill in the options descriptions accordingly.
Definition: rm.cc:24
po::variables_map & vm()
Get the variables map.
Definition: Handlers.cc:145
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 Supercell & get_supercell(Index i) const
const Access supercell by index
Definition: PrimClex.cc:311
void error(const std::string &what)
Definition: Log.hh:86
bool dry_run() const
Definition: rm.cc:20
ConfigIO::GenericConfigFormatter< std::string > scelname()
Definition: ConfigIO.cc:348
bool contains_supercell(std::string scellname, Index &index) const
Definition: PrimClex.cc:709
bool force() const
Definition: rm.cc:16
#define ERR_NO_PROJ