bool P4Command::MapToLocal(P4Task& task, VersionedAssetList& assets) { const vector<Mapping>& mappings = GetMappings(task, assets); if (mappings.size() != assets.size()) return false; // error vector<Mapping>::const_iterator m = mappings.begin(); for (VersionedAssetList::iterator i = assets.begin(); i != assets.end(); ++i, ++m) { i->SetPath(m->clientPath); } return true; }
virtual bool Run(P4Task& task, const CommandArgs& args) { ClearStatus(); Conn().Log().Info() << args[0] << "::Run()" << Endl; bool noLocalFileMove = args.size() > 1 && args[1] == "noLocalFileMove"; VersionedAssetList assetList; Conn() >> assetList; if ( assetList.empty() ) { Conn().EndResponse(); return true; } // Process two assets at a time ie. src,dest if ( assetList.size() % 2 ) { Conn().WarnLine("uneven number of assets during move", MASystem); Conn().EndResponse(); return true; } VersionedAssetList::const_iterator b = assetList.begin(); VersionedAssetList::const_iterator e = b; // Split into two steps. 1st make everything editable and 2nd do the move. // this makes changes more atomic. while (b != assetList.end()) { e += 2; const VersionedAsset& src = *b; string paths = ResolvePaths(b, e, kPathWild | kPathRecursive); Conn().Log().Debug() << "Ensure editable source " << paths << Endl; string err; bool editable = (src.GetState() & (kCheckedOutLocal | kAddedLocal | kLockedLocal)) != 0; if (!editable) { string srcPath = ResolvePaths(b, b+1, kPathWild | kPathRecursive); Conn().Log().Info() << "edit " << srcPath << Endl; if (!task.CommandRun("edit " + srcPath, this)) { break; } } b = e; } b = assetList.begin(); e = b; VersionedAssetList targetAssetList; string noLocalFileMoveFlag = noLocalFileMove ? " -k " : ""; while (!HasErrors() && b != assetList.end()) { e += 2; const VersionedAsset& src = *b; const VersionedAsset& dest = *(b+1); targetAssetList.push_back(dest); string paths = ResolvePaths(b, e, kPathWild | kPathRecursive); Conn().Log().Info() << "move " << noLocalFileMoveFlag << paths << Endl; if (!task.CommandRun("move " + noLocalFileMoveFlag + paths, this)) { break; } // Make the actual file system move if perforce didn't do it ie. in // the case of an empty folder rename or a non versioned asset/folder move/rename if (!PathExists(dest.GetPath())) { // Move the file if (!MoveAFile(src.GetPath(), dest.GetPath())) { string errorMessage = "Error moving file "; errorMessage += src.GetPath(); errorMessage += " to "; errorMessage += dest.GetPath(); Conn().WarnLine(errorMessage); } } // Delete move folder src since perforce leaves around empty folders. // This only works because unity will not send embedded moves. if (src.IsFolder() && IsDirectory(src.GetPath())) { DeleteRecursive(src.GetPath()); } b = e; } // We just wrap up the communication here. Conn() << GetStatus(); RunAndSendStatus(task, targetAssetList); Conn().EndResponse(); return true; }