16 #include "cvsSourceDirectory.h" 29 _key_filename =
"Sources.pp";
31 _user_aborted =
false;
36 add_runline(
"[opts] file [file ... ]");
40 "Force the copy to happen without any input from the user. If a file " 41 "with the same name exists anywhere in the source hierarchy, it will " 42 "be overwritten without prompting; if a file does not yet exist, it " 43 "will be created in the directory named by -d or by -m, as appropriate.",
44 &CVSCopy::dispatch_none, &_force);
48 "The opposite of -f, this will prompt the user before each action. " 49 "The default is only to prompt the user when an action is ambiguous " 51 &CVSCopy::dispatch_none, &_interactive);
55 "Copy model files that are not already present somewhere in the tree " 56 "to the indicated directory. The default is the current directory.",
57 &CVSCopy::dispatch_filename, &_got_model_dirname, &_model_dirname);
61 "Copy texture map files to the indicated directory. The default " 62 "is src/maps from the root directory.",
63 &CVSCopy::dispatch_filename, &_got_map_dirname, &_map_dirname);
66 (
"root",
"dirname", 80,
67 "Specify the root of the CVS source hierarchy. The default is to " 68 "use the ppremake convention of locating the directory above the -d " 69 "directory that contains a file called Package.pp.",
70 &CVSCopy::dispatch_filename, &_got_root_dirname, &_root_dirname);
73 (
"key",
"filename", 80,
74 "Specify the name of the file that must exist in each directory for " 75 "it to be considered part of the CVS source hierarchy. The default " 76 "is the ppremake convention, \"Sources.pp\". Other likely candidates " 77 "are \"CVS\" to search a CVS hierarchy, or \".\" to include " 78 "all subdirectories indiscriminately.",
79 &CVSCopy::dispatch_filename, NULL, &_key_filename);
83 "Do not attempt to add newly-created files to CVS. The default " 85 &CVSCopy::dispatch_none, &_no_cvs);
88 (
"cvs",
"cvs_binary", 80,
89 "Specify how to run the cvs program for adding newly-created files. " 90 "The default is simply \"cvs\".",
91 &CVSCopy::dispatch_string, NULL, &_cvs_binary);
115 CopiedFiles::const_iterator ci;
116 ci = _copied_files.find(source);
117 if (ci != _copied_files.end()) {
123 nout <<
"Source filename " << source <<
" does not exist!\n";
127 string basename = filter_filename(source.
get_basename());
131 nassertr(path.is_valid(), path);
133 _copied_files[source] = path;
136 bool new_file = !dest.
exists();
137 if (!new_file && verify_file(source, dest, path._dir, extra_data)) {
139 nout << path.get_path() <<
" is unchanged.\n";
143 nout <<
"Copying " << basename <<
" to " << path.get_path() <<
"\n";
145 if (!copy_file(source, dest, path._dir, extra_data, new_file)) {
177 string result = prompt(
"Error occurred during copy! Continue (y/n)? ");
178 nassertr(!result.empty(),
false);
179 if (result.size() == 1) {
180 if (tolower(result[0]) ==
'y') {
182 }
else if (tolower(result[0]) ==
'n') {
183 _user_aborted =
true;
188 nout <<
"*** Invalid response: " << result <<
"\n\n";
202 handle_args(
Args &args) {
204 nout <<
"You must specify the file(s) to copy from on the command line.\n";
208 for (Args::const_iterator ai = args.begin();
227 post_command_line() {
228 if (!scan_hierarchy()) {
234 if (_got_model_dirname) {
235 nout <<
"Warning: model directory " << _model_dirname
236 <<
" is not within the source hierarchy.\n";
240 if (_got_map_dirname) {
244 nout <<
"Warning: map directory " << _map_dirname
245 <<
" is not within the source hierarchy.\n";
254 _map_dir = _model_dir;
284 if (source == dest) {
302 while (!s.eof() && !s.fail() && !d.eof() && !d.fail()) {
310 if (s.fail() || d.fail()) {
318 if (!s.eof() || !d.eof()) {
338 if (source == dest) {
348 nout <<
"Cannot read " << source <<
"\n";
354 nout <<
"Cannot write " << dest <<
"\n";
360 while (!in.eof() && !in.fail() && !out.fail()) {
365 if (!in.eof() && in.fail()) {
366 nout <<
"Error reading " << source <<
"\n";
370 nout <<
"Error writing " << dest <<
"\n";
391 nout <<
"Invalid directory: " << filename.
get_dirname() <<
"\n";
395 string command = _cvs_binary +
" add -kb " +
397 nout << command <<
"\n";
398 int result = system(command.c_str());
403 nout <<
"Failure invoking cvs.\n";
418 protect_from_shell(
const string &source) {
421 for (string::const_iterator pi = source.begin(); pi != source.end(); ++pi) {
462 filter_filename(
const string &source) {
477 if (!_got_root_dirname) {
480 if (!scan_for_root(_model_dirname)) {
488 return _tree.
scan(_key_filename);
500 scan_for_root(
const string &dirname) {
501 Filename sources = dirname +
"/Sources.pp";
503 nout <<
"Couldn't find " << sources <<
" in source directory.\n";
506 Filename package = dirname + "/Package.pp";
507 if (package.exists()) {
509 _root_dirname = dirname;
513 return scan_for_root(dirname +
"/..");
524 prompt(
const string &message) {
527 cerr << message << flush;
529 getline(cin, response);
533 while (p < response.length() && isspace(response[p])) {
537 size_t q = response.length();
538 while (q > p && isspace(response[q - 1])) {
543 return response.substr(p, q - p);
string get_dirname() const
Returns the directory part of the filename.
string get_basename() const
Returns the basename part of the filename.
CVSSourceTree::FilePath import(const Filename &source, void *extra_data, CVSSourceDirectory *suggested_dir)
Checks for the given filename somewhere in the directory hierarchy, and chooses a place to import it...
bool open_write(ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
FilePath choose_directory(const string &basename, CVSSourceDirectory *suggested_dir, bool force, bool interactive)
Determines where an externally referenced model file of the indicated name should go...
Filename get_root_dirname() const
Returns the local directory name of the root of the tree.
string get_fullpath() const
Returns the entire filename: directory, basename, extension.
void set_binary()
Indicates that the filename represents a binary file.
void set_root(const Filename &root_path)
Sets the root of the source directory.
Filename get_root_fullpath()
Returns the full path from the root to the top of the source hierarchy.
CVSSourceDirectory * find_directory(const Filename &path)
Returns the source directory that corresponds to the given path, or NULL if there is no such director...
bool open_read(ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
CVSSourceDirectory * find_relpath(const string &relpath)
Returns the source directory that corresponds to the given relative path from the root...
This represents one particular directory in the hierarchy of source directory files.
The name of a file, such as a texture file or an Egg file.
static bool temp_chdir(const Filename &path)
Temporarily changes the current directory to the named path.
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
bool continue_after_error()
Prompts the user (unless -f was specified) if he wants to continue the copy operation after some erro...
bool scan(const Filename &key_filename)
Scans the complete source directory starting at the indicated pathname.
static void restore_cwd()
Restores the current directory after changing it from temp_chdir().
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).