/* Add, delete or query the pristine trees in the project tree. Copyright (C) 2001, 2002 Tom Lord Copyright (C) 2002, 2003 Walter Landry and the Regents of the University of California Copyright (C) 2004 Walter Landry This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 dated June, 1991. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "parse_common_options.hpp" #include "parse_unknown_options.hpp" #include "Parsed_Name.hpp" #include "check_extra_args.hpp" #include "command_initializer.hpp" #include "arx_error.hpp" #include #include "get_config_option.hpp" #include "get_option_from_file.hpp" #include "boost/filesystem/operations.hpp" #include "get_revision.hpp" #include "valid_package_name.hpp" #include "tree_root.hpp" #include "latest_tree_revision.hpp" #include #include "patch_level.hpp" #include "Revision_List.hpp" #include "list_tree_cached_revisions.hpp" #include "add_tree_cache.hpp" using namespace std; using namespace boost; namespace fs=boost::filesystem; using fs::path; int tree_cache(list &argument_list, const command &cmd); static command_initializer tree_cache_init(command("tree-cache", "Manipulate cached revisions in the project tree", "usage: tree-cache [options] [branch]\n\ or: tree-cache [options] --add [revision]\n\ or: tree-cache [options] --delete revision", " -a --add Add a cached revision to the project tree\n\ -d --delete Remove a cached revision from the project tree\n\ --dir DIR change to DIR first\n\ --cache CACHE-DIR cache directory for locally cached revisions\n\ \n\ Without any options, it will print out all of the revisions cached\n\ in the project tree for DIR (or the current directory). With --add, it\n\ adds the indicated revision to the local cache of current project tree.\n\ If no revision is supplied, then it will add the last revision of the\n\ project tree's default branch (see \"tree-branch\").\n\ \n\ With --delete, it removes that cached revision from the project tree,\n\ freeing up space. For --delete a revision is required.", tree_cache,"Administrative",true)); int tree_cache(list &argument_list, const command &cmd) { Command_Info info(cmd); bool add(false), remove(false); path tree_directory(fs::current_path()), cache_dir(fs::current_path()); while(!argument_list.empty()) if(!parse_common_options(argument_list,info)) { if(*(argument_list.begin())=="-d" || *(argument_list.begin())=="--delete") { remove=true; argument_list.pop_front(); } else if(*(argument_list.begin())=="-a" || *(argument_list.begin())=="--add") { add=true; argument_list.pop_front(); } else if(*(argument_list.begin())=="--cache") { argument_list.pop_front(); if(argument_list.empty()) { throw arx_error("Need an argument for --cache"); } cache_dir=path(*(argument_list.begin())); argument_list.pop_front(); } else if(*(argument_list.begin())=="--dir") { argument_list.pop_front(); if(argument_list.empty()) { throw arx_error("Need an argument for --dir"); } tree_directory=path(*(argument_list.begin())); argument_list.pop_front(); } else { parse_unknown_options(argument_list); break; } } if(add && remove) throw arx_error("You may not both add and delete a cached revision."); /* Get the revision to add, delete or query. */ Parsed_Name input_revision; if(!argument_list.empty()) { input_revision=Parsed_Name(*(argument_list.begin())); argument_list.pop_front(); if(add || remove) valid_package_name(input_revision,Revision); } else if(add) { input_revision=latest_tree_revision(tree_directory); } else if(remove) { throw arx_error("You must explicitly specify a revision when deleting a cached revision."); } check_extra_args(argument_list,info); list pristines(list_tree_cached_revisions(tree_directory, input_revision)); /* Add a cached tree */ if(add) { if(!pristines.empty()) { if(info.verbosity>=default_output) cerr << "This revision is already cached in the project tree.\n\t" << input_revision.full_name() << "\n\t" << tree_directory.native_file_string() << endl; } else { add_tree_cache(tree_directory,cache_dir,input_revision); } } /* Delete a cached tree */ else if(remove) { if(pristines.empty()) { if(info.verbosity>=default_output) cerr << "This revision is not cached in the project tree.\n\t" << input_revision.full_name() << "\n\t" << tree_directory.native_file_string() << endl; } else { /* This is a little messy, because it doesn't clean up the empty directories (Lazy). I doubt it makes a difference in practice. */ fs::remove_all((tree_root(tree_directory)/ "_arx/++cache") / input_revision.revision_path()); } } /* List the cached trees */ else { if(info.verbosity>=default_output) for(list::iterator i=pristines.begin(); i!=pristines.end(); ++i) for(list::iterator j=i->begin(); j!=i->end(); ++j) cout << i->name.complete_branch() << patch_level(*j) << endl; } return 0; }