From 5abc5cf9f836016d1236da84a54ae3441a264806 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 2 Nov 2013 20:18:13 +0100 Subject: [PATCH] Lots of little fixes for import, status should be imported mostly OK now. A dded a migration_steps.txt that outlines the steps to migrate data. Still todo: * Extensions/addons, skipped now, will do next week * Hide some unnecessary transactions * Figure out policies for tasks and projects * Test run over all tasks to see that they work --- migration/dedup.php | 4 - migration/export_all_tasks.sh | 10 - migration/export_task.php | 95 ++-- migration/export_users.php | 18 +- migration/import_all_tasks.sh | 10 - migration/import_projects.php | 4 +- migration/import_task.php | 824 ++++++++++++++++++---------------- migration/import_users.php | 195 ++++---- migration/migration_steps.txt | 142 ++++++ migration/phab.php | 368 ++++++++------- migration/storage.php | 104 ++--- 11 files changed, 974 insertions(+), 800 deletions(-) delete mode 100755 migration/export_all_tasks.sh delete mode 100755 migration/import_all_tasks.sh create mode 100644 migration/migration_steps.txt diff --git a/migration/dedup.php b/migration/dedup.php index 0fa75d7539..39f4ddabad 100644 --- a/migration/dedup.php +++ b/migration/dedup.php @@ -2,10 +2,6 @@ $migrate_dedup_users = array(); -// XXX -$migrate_dedup_users["quick_testing_hack"] = "brechtvl"; -$migrate_dedup_users["quick_testing_more"] = "brechtvl"; - $migrate_dedup_users["midiclub"] = "midclub"; $migrate_dedup_users["trip"] = "car"; $migrate_dedup_users["thunderbolt"] = "thunderbolt16"; diff --git a/migration/export_all_tasks.sh b/migration/export_all_tasks.sh deleted file mode 100755 index 516c093f4b..0000000000 --- a/migration/export_all_tasks.sh +++ /dev/null @@ -1,10 +0,0 @@ - -./export_task.php 1 5000 -./export_task.php 5000 10000 -./export_task.php 10000 15000 -./export_task.php 15000 20000 -./export_task.php 20000 25000 -./export_task.php 25000 30000 -./export_task.php 30000 35000 -./export_task.php 35000 38000 - diff --git a/migration/export_task.php b/migration/export_task.php index 1d3378b4a5..15adb7a954 100755 --- a/migration/export_task.php +++ b/migration/export_task.php @@ -29,8 +29,8 @@ require_once 'storage.php'; function lookup_user_name($user_id) { - $res = db_query_params ('SELECT user_name FROM users WHERE user_id=$1', array($user_id)); - return db_result($res, 0, 'user_name'); + $res = db_query_params ('SELECT user_name FROM users WHERE user_id=$1', array($user_id)); + return db_result($res, 0, 'user_name'); } for ($aid=intval($argv[1]); $aidisError()) { - echo "SKIP " . $aid . "\n"; - continue; - } else { - echo "GO " . $aid . "\n"; - $group_id=$a->ArtifactType->Group->getID(); - $atid=$a->ArtifactType->getID(); - } + if (!$a || !is_object($a) || $a->isError()) { + echo "SKIP " . $aid . "\n"; + continue; + } else { + echo "GO " . $aid . "\n"; + $group_id=$a->ArtifactType->Group->getID(); + $atid=$a->ArtifactType->getID(); + } } $group =& group_get_object($group_id); if (!$group || !is_object($group) || $group->isError()) - echo "Group invalid\n"; + echo "Group invalid\n"; $ath = new ArtifactTypeHtml($group,$atid); if (!$ath || !is_object($ath) || $ath->isError()) - echo "Artifact type invalid\n"; + echo "Artifact type invalid\n"; $ah=new ArtifactHtml($ath,$aid); if (!$ah || !is_object($ah) || $ah->isError()) - echo "Artifact invalid\n"; + echo "Artifact invalid\n"; /* create task */ $mtasks = array(); @@ -88,11 +88,11 @@ $result= $ah->getMessages(); $rows=db_numrows($result); for ($i=0; $i < $rows; $i++) { - $mcomment = new MigrateComment(); - $mcomment->user = db_result($result, $i,'user_name'); - $mcomment->description = db_result($result, $i, 'body'); - $mcomment->date = db_result($result, $i, 'adddate'); - $mtask->comments[] = $mcomment; + $mcomment = new MigrateComment(); + $mcomment->user = db_result($result, $i,'user_name'); + $mcomment->description = db_result($result, $i, 'body'); + $mcomment->date = db_result($result, $i, 'adddate'); + $mtask->comments[] = $mcomment; } /* history */ @@ -103,37 +103,36 @@ $historyrows= db_numrows($history); $file_list =& $ah->getFiles(); $rows=count($file_list); -// TODO skipping attachments for now -/*for ($i=0; $i<$rows; $i++) { - $af = $file_list[$i]; +for ($i=0; $i<$rows; $i++) { + $af = $file_list[$i]; - $afd=new ArtifactFile($ah,$af->getID()); + $afd=new ArtifactFile($ah,$af->getID()); - $fileuser = null; + $fileuser = null; - for ($j=0; $j < $historyrows; $j++) { - $hvalue = db_result($history, $j, 'old_value'); - if($hvalue == $af->getID() + ": " + $af->getName()) - $fileuser = db_result($history, $j, 'user_name'); - } + for ($j=0; $j < $historyrows; $j++) { + $hvalue = db_result($history, $j, 'old_value'); + if($hvalue == $af->getID() + ": " + $af->getName()) + $fileuser = db_result($history, $j, 'user_name'); + } - $mfile = new MigrateFile(); - $mfile->user = $fileuser; - $mfile->name = $af->getName(); - $mfile->date = $af->getDate(); - $mfile->type = $af->getType(); - $mfile->contents = $afd->getData(); - $mtask->files[] = $mfile; -}*/ + $mfile = new MigrateFile(); + $mfile->user = $fileuser; + $mfile->name = $af->getName(); + $mfile->date = $af->getDate(); + $mfile->type = $af->getType(); + $mfile->contents = $afd->getData(); + $mtask->files[] = $mfile; +} /* history */ for ($i=0; $i < $historyrows; $i++) { - $mhistory = new MigrateHistory(); - $mhistory->user = db_result($history, $i, 'user_name'); - $mhistory->date = db_result($history, $i, 'entrydate'); - $mhistory->field = db_result($history, $i, 'field_name'); - $mhistory->old = db_result($history, $i, 'old_value'); - $mtask->history[] = $mhistory; + $mhistory = new MigrateHistory(); + $mhistory->user = db_result($history, $i, 'user_name'); + $mhistory->date = db_result($history, $i, 'entrydate'); + $mhistory->field = db_result($history, $i, 'field_name'); + $mhistory->old = db_result($history, $i, 'old_value'); + $mtask->history[] = $mhistory; } /* subscribers */ @@ -142,19 +141,19 @@ $ccids = util_result_column_to_array($res); $ccs = array(); foreach($ccids as $ccid) - if($ccid) - $ccs[] = lookup_user_name($ccid); + if($ccid) + $ccs[] = lookup_user_name($ccid); if($ah->getAssignedTo()) - $ccs[] = lookup_user_name($ah->getAssignedTo()); + $ccs[] = lookup_user_name($ah->getAssignedTo()); if($ah->getSubmittedBy()) - $ccs[] = lookup_user_name($ah->getSubmittedBy()); + $ccs[] = lookup_user_name($ah->getSubmittedBy()); $result= $ah->getMessages(); $rows=db_numrows($result); for ($i=0; $i < $rows; $i++) - $ccs[] = lookup_user_name(db_result($result,$i,'user_id')); + $ccs[] = lookup_user_name(db_result($result,$i,'user_id')); $mtask->ccs = array_unique($ccs); $mtask->extra_fields = $ah->getExtraFieldDataText(); diff --git a/migration/export_users.php b/migration/export_users.php index b01db7fa02..35fa7bb8ac 100755 --- a/migration/export_users.php +++ b/migration/export_users.php @@ -38,16 +38,16 @@ $musers = array(); for ($i = 0; $i < count ($user_names); $i++) { - $muser = new MigrateUser(); - $muser->id = $user_ids[$i]; - $muser->password = $user_pws[$i]; - $muser->name = $user_names[$i]; - $muser->realname = trim($user_realnames[$i]); - $muser->email = $user_emails[$i]; - $muser->date = $user_dates[$i]; - $muser->timezone = $user_timezones[$i]; + $muser = new MigrateUser(); + $muser->id = $user_ids[$i]; + $muser->password = $user_pws[$i]; + $muser->name = $user_names[$i]; + $muser->realname = trim($user_realnames[$i]); + $muser->email = $user_emails[$i]; + $muser->date = $user_dates[$i]; + $muser->timezone = $user_timezones[$i]; - $musers[] = $muser; + $musers[] = $muser; } file_put_contents('dump/users', serialize($musers)); diff --git a/migration/import_all_tasks.sh b/migration/import_all_tasks.sh deleted file mode 100755 index 98952f1916..0000000000 --- a/migration/import_all_tasks.sh +++ /dev/null @@ -1,10 +0,0 @@ - -./import_task.php 1 5000 -./import_task.php 5000 10000 -./import_task.php 10000 15000 -./import_task.php 15000 20000 -./import_task.php 20000 25000 -./import_task.php 25000 30000 -./import_task.php 30000 35000 -./import_task.php 35000 38000 - diff --git a/migration/import_projects.php b/migration/import_projects.php index dcc4f4eb5a..0d1fd7a848 100755 --- a/migration/import_projects.php +++ b/migration/import_projects.php @@ -7,11 +7,9 @@ require_once 'storage.php'; require_once 'adapt.php'; require_once 'phab.php'; -// TODO: add all necessary projects - /* projects */ create_project("BF Blender", "None", true, $bf_developers, "Blender Foundation official release."); -create_project("Extensions", "None", true, $addon_developers, "Addon scripts and plugins for Blender."); +create_project("Addons", "None", true, $addon_developers, "Addon scripts and plugins for Blender."); create_project("Translations", "None", true, $translation_developers, "Localization of Blender in different languages."); /* modules */ diff --git a/migration/import_task.php b/migration/import_task.php index 68f1e5b33b..9da8531e0e 100755 --- a/migration/import_task.php +++ b/migration/import_task.php @@ -8,423 +8,487 @@ require_once 'adapt.php'; require_once 'phab.php'; for($id = intval($argv[1]); $id < intval($argv[2]); $id+=1) { - /* unserialize */ - $fname = "dump/task_" . $id; - if(!file_exists($fname)) - continue; - - //echo "IMPORT " . $id . "\n"; + /* unserialize */ + $fname = "dump/task_" . $id; + if(!file_exists($fname)) + continue; + + //echo "IMPORT " . $id . "\n"; - $fcontents = file_get_contents($fname); - $mtask = unserialize($fcontents); + $fcontents = file_get_contents($fname); + $mtask = unserialize($fcontents); - /* extract basic data */ - $author = lookup_user(dedup_user($mtask->author)); - $assign = lookup_user(dedup_user($mtask->assign)); - $projects = array(); - // 100 Unbreak Now!, 90 Needs Triage, 80 High, 50 Normal, 25 Low, 0, Wishlist - $status = ManiphestTaskStatus::STATUS_OPEN; - $description = '%%%' . html_entity_decode($mtask->description) . '%%%'; // TODO replace urls - $title = html_entity_decode($mtask->title); + /* extract basic data */ + $author = lookup_user(dedup_user($mtask->author)); + $assign = lookup_user(dedup_user($mtask->assign)); + $projects = array(); + $status = ManiphestTaskStatus::STATUS_OPEN; + $description = '%%%' . html_entity_decode($mtask->description) . '%%%'; + $title = html_entity_decode($mtask->title); - /* spam detection */ - if(($author == "None" || $author == null) && startsWith($description, "%%%getUsername() == "None") - $assign = null; - - /* extra fields */ - $extra = ""; - $extension_type = "None"; - $task_type = "Bug"; + /* missing author */ + if($author == null) + $author = lookup_user("None"); + + if($assign && $assign->getUsername() == "None") + $assign = null; + + /* extra fields */ + $extra = ""; + $task_type = "Bug"; + $remove_subscribers = false; - /* BF Blender tasks */ - if($mtask->project == "Blender 2.x BF release") { - $projects[] = lookup_project("BF Blender")->getPHID(); - $category = null; - $category_key = null; - $mstatus = null; - $mstatus_key = null; - $resolution = null; - $resolution_key = null; - $old_resolution = null; - $old_resolution_key = null; - $data_type = null; - $date_type_key = null; + /* BF Blender tasks */ + if($mtask->project == "Blender 2.x BF release") { + $category = null; + $category_key = null; + $mstatus = null; + $mstatus_key = null; + $resolution = null; + $resolution_key = null; + $old_resolution = null; + $old_resolution_key = null; + $data_type = null; + $date_type_key = null; - foreach($mtask->extra_fields as $key => $field) { - if($field['name'] == "Category") { - $category = $field['value']; - $category_key = $key; - } - else if($field['name'] == "Status") { - $mstatus = $field['value']; - $mstatus_key = $key; - } - else if($field['name'] == "Resolution") { - $resolution = $field['value']; - $resolution_key = $key; - } - else if($field['name'] == "Resolution(Old, use status)") { - $old_resolution = $field['value']; - $old_resolution_key = $key; - } - else if($field['name'] == "Data Type") { - $data_type = $field['value']; - $data_type_key = $key; - } - } + foreach($mtask->extra_fields as $key => $field) { + if($field['name'] == "Category") { + $category = $field['value']; + $category_key = $key; + } + else if($field['name'] == "Status") { + $mstatus = $field['value']; + $mstatus_key = $key; + } + else if($field['name'] == "Resolution") { + $resolution = $field['value']; + $resolution_key = $key; + } + else if($field['name'] == "Resolution(Old, use status)") { + $old_resolution = $field['value']; + $old_resolution_key = $key; + } + else if($field['name'] == "Data Type") { + $data_type = $field['value']; + $data_type_key = $key; + } + } - if($mtask->tracker == "Blender 2.6 Bug Tracker") { - $close_as_archived = false; - $task_type = "Bug"; - $priority = 50; + if($mtask->tracker == "Blender 2.6 Bug Tracker") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $close_as_archived = false; + $task_type = "Bug"; + $priority = 40; - if($category) { - if($bf_blender_categories[$category]) - $projects[] = lookup_project($bf_blender_categories[$category])->getPHID(); - unset($mtask->extra_fields[$category_key]); - } + if($category) { + if($bf_blender_categories[$category]) + $projects[] = lookup_project($bf_blender_categories[$category])->getPHID(); + unset($mtask->extra_fields[$category_key]); + } - // TODO: add more statuses or fields - switch($mstatus) { - case "New": - $priority = 90; - break; - case "Reopened": - break; - case "Investigate": - break; - case "Confirmed": - break; - case "Incomplete": - break; - case "Fixed / Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; - break; - case "Rejected / Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; - break; - case "Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - break; - case "Todo / Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; - break; - case "Out of scope / Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; - break; - case "Ready": - break; - case "*RELEASE BLOCKER*": - $priority = 80; - break; - default: - echo "ERROR: unkown status \"" . $mstatus . "\" (" . $id . ")\n"; - break; - } + switch($mstatus) { + case "New": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Reopened": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Investigate": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Confirmed": + $priority = 50; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Incomplete": + $priority = 30; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Fixed / Closed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + case "Rejected / Closed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + case "Closed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + case "Todo / Closed": + $task_type = "To Do"; + $priority = 40; + $assign = null; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + break; + case "Out of scope / Closed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + case "Ready": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "*RELEASE BLOCKER*": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + default: + echo "ERROR: unkown status \"" . $mstatus . "\" (" . $id . ")\n"; + break; + } - unset($mtask->extra_fields[$mstatus_key]); - } - else if($mtask->tracker == "Blender 2.4x Bug Tracker") { - // TODO: handle status - $task_type = "Bug"; - $priority = 50; - $close_as_archived = true; - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - } - else if($mtask->tracker == "Game Engine") { - // TODO: add more statuses or fields - switch($mstatus) { - case "None": - case "New": - case "Reopened": - case "Investigate": - case "Ready": - $status = ManiphestTaskStatus::STATUS_OPEN; - break; - case "Fixed": - $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; - break; - case "Duplicate": - $status = ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE; - break; - case "Rejected": - $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; - break; - case "Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; - break; - default: - echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n"; - break; - } + unset($mtask->extra_fields[$mstatus_key]); + } + else if($mtask->tracker == "Blender 2.4x Bug Tracker") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $task_type = "Bug"; + $priority = 20; + $close_as_archived = true; + $remove_subscribers = true; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + } + else if($mtask->tracker == "Game Engine") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $projects[] = lookup_project("Game Engine")->getPHID(); + $task_type = "Bug"; + $priority = 40; + $close_as_archived = false; + $status = ManiphestTaskStatus::STATUS_OPEN; - unset($mtask->extra_fields[$mstatus_key]); + switch($mstatus) { + case "New": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "None": + case "Reopened": + case "Investigate": + case "Ready": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Fixed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + case "Duplicate": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_DUPLICATE; + break; + case "Rejected": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + case "Closed": + $priority = 40; + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + default: + echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n"; + break; + } - $projects[] = lookup_project("Game Engine")->getPHID(); - $task_type = "Bug"; - $priority = 50; - $close_as_archived = false; - $status = ManiphestTaskStatus::STATUS_OPEN; - } - else if($mtask->tracker == "Todo") { - $task_type = "To Do"; - $priority = 0; - $close_as_archived = false; - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - } - else if($mtask->tracker == "OpenGL errors") { - $task_type = "OpenGL Error"; - $priority = 25; - $close_as_archived = false; - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - } - else if($mtask->tracker == "Patches") { - $task_type = "Patch"; - $priority = 50; - $close_as_archived = false; + unset($mtask->extra_fields[$mstatus_key]); + } + else if($mtask->tracker == "Todo") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $task_type = "To Do"; + $assign = null; + $priority = 20; + $close_as_archived = false; + $remove_subscribers = true; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + } + else if($mtask->tracker == "OpenGL errors") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $task_type = "OpenGL Error"; + $priority = 20; + $close_as_archived = false; + $remove_subscribers = true; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + } + else if($mtask->tracker == "Patches") { + $projects[] = lookup_project("BF Blender")->getPHID(); + $task_type = "Patch"; + $priority = 40; + $close_as_archived = false; - if($category) { - if($bf_blender_categories[$category]) - $projects[] = lookup_project($bf_blender_categories[$category])->getPHID(); - unset($mtask->extra_fields[$category_key]); - } + if($category) { + if($bf_blender_categories[$category]) + $projects[] = lookup_project($bf_blender_categories[$category])->getPHID(); + unset($mtask->extra_fields[$category_key]); + } - // TODO: add more statuses or fields - switch($resolution) { - case "None": - $status = ManiphestTaskStatus::STATUS_OPEN; - break; - case "Open": - $status = ManiphestTaskStatus::STATUS_OPEN; - break; - case "Investigate": - $status = ManiphestTaskStatus::STATUS_OPEN; - break; - case "Need updates": - $status = ManiphestTaskStatus::STATUS_OPEN; - break; - case "Applied": - $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; - break; - case "Closed": - $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; - break; - default: - echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n"; - break; - } + switch($resolution) { + case "None": + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Open": + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Investigate": + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Need updates": + $priority = 30; + $status = ManiphestTaskStatus::STATUS_OPEN; + break; + case "Applied": + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + case "Closed": + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + default: + echo "ERROR: unkown resolution \"" . $resolution . "\" (" . $id . ")\n"; + break; + } - unset($mtask->extra_fields[$resolution_key]); - if($old_resolution) - unset($mtask->extra_fields[$old_resolution_key]); - } - else { - echo "ERROR: unknown BF Blender tracker " . $mtask->tracker . " (" . $id . ")\n"; - $priority = 50; - $close_as_archived = true; - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - } - } - else if($mtask->project == "Blender Extensions") { - switch($mtask->tracker) { - case "Py Scripts Extern": - $extension_type = "Python Script Extern"; - break; - case "dev-tools": - break; - case "test-tracker": - break; - case "Plugins Release": - $extension_type = "Plugin Release"; - break; - case "Plugins Contrib": - $extension_type = "Plugin Contrib"; - break; - case "Plugins Upload": - $extension_type = "Plugin Upload"; - break; - case "Py Scripts Release": - $extension_type = "Pythin Script Release"; - break; - case "Py Scripts Contrib": - $extension_type = "Python Script Contrib"; - break; - case "Py Scripts Upload": - $extension_type = "Python Script Upload"; - break; - case "Bugs": - break; - default: - echo "ERROR: unkown extension tracker \"" . $mtask->tracker . "\" (" . $id . ")\n"; - break; - } + if($status == ManiphestTaskStatus::STATUS_OPEN) { + switch($old_resolution) { + case "Approved": + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + case "Rejected": + $status = ManiphestTaskStatus::STATUS_CLOSED_INVALID; + break; + case "Postponed": + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + break; + case "Fixed": + $status = ManiphestTaskStatus::STATUS_CLOSED_RESOLVED; + break; + } - // TODO: status! + /* weird stuff goes on here, seems there are closed patches + * that do no show any closed resolution, so force it */ + if($mtask->state == "Closed") + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + } - $projects[] = lookup_project("Extensions")->getPHID(); - $task_type = "Extension"; - $priority = 50; - $status = ManiphestTaskStatus::STATUS_OPEN; - $close_as_archived = false; - } - else { - $extra .= "**Project**: " . $mtask->project . "\n"; - $extra .= "**Tracker**: " . $mtask->tracker . "\n"; + unset($mtask->extra_fields[$resolution_key]); + if($old_resolution) + unset($mtask->extra_fields[$old_resolution_key]); + } + else { + $projects[] = lookup_project("BF Blender")->getPHID(); + echo "ERROR: unknown BF Blender tracker " . $mtask->tracker . " (" . $id . ")\n"; + $priority = 20; + $close_as_archived = true; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + $remove_subscribers = true; + } + } + else if($mtask->project == "Blender Extensions") { + // TODO: import extensions as addons + // split bugs and leave out extensions - $task_type = "Other"; - $priority = 50; - $close_as_archived = true; - $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; - } + /* switch($mtask->tracker) { + case "Py Scripts Extern": + $extension_type = "Python Script Extern"; + break; + case "dev-tools": + break; + case "test-tracker": + break; + case "Plugins Release": + $extension_type = "Plugin Release"; + break; + case "Plugins Contrib": + $extension_type = "Plugin Contrib"; + break; + case "Plugins Upload": + $extension_type = "Plugin Upload"; + break; + case "Py Scripts Release": + $extension_type = "Python Script Release"; + break; + case "Py Scripts Contrib": + $extension_type = "Python Script Contrib"; + break; + case "Py Scripts Upload": + $extension_type = "Python Script Upload"; + break; + case "Bugs": + break; + default: + echo "ERROR: unkown extension tracker \"" . $mtask->tracker . "\" (" . $id . ")\n"; + break; + } - /* add remaining extra fields to description */ - foreach($mtask->extra_fields as $field) { - if($field['value'] == "" || $field['value'] == 'None') - continue; + $projects[] = lookup_project("Addons")->getPHID(); + $task_type = "Extension"; + $priority = 50; + $status = ManiphestTaskStatus::STATUS_OPEN; + $close_as_archived = false;*/ - if($field['name'] == 'Relates to') { - $extra .= "**Relates to**: "; - } - else if($field['name'] == 'Related to') { - $extra .= "**Related to**: "; - } - else if($field['name'] == 'Duplicate') { - $extra .= "**Duplicate**: "; - } - else if($field['name'] == 'Duplicates') { - $extra .= "**Duplicates**: "; - } - else if($field['name'] == 'Patches') { - $extra .= "**Patches**: "; - } - else if($field['name'] == 'Patch for') { - $extra .= "**Patch for**: "; - } - else { - $extra .= "**" . $field['name'] . "**: " . $field['value'] . "\n"; - continue; - } + continue; + } + else { + $extra .= "**Project**: " . $mtask->project . "\n"; + $extra .= "**Tracker**: " . $mtask->tracker . "\n"; - $value = explode(" ", str_replace("#", "", $field['value'])); - $first = true; - foreach($value as $subvalue) { - if($first) - $first = false; - else - $extra .= " "; + $task_type = "Other"; + $priority = 20; + $close_as_archived = true; + $status = ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED; + $remove_subscribers = true; + } - $extra .= "T" . $subvalue; - } + /* add remaining extra fields to description */ + foreach($mtask->extra_fields as $field) { + if($field['value'] == "" || $field['value'] == 'None') + continue; - $extra .= "\n"; - } + if($field['name'] == 'Relates to') { + $extra .= "**Relates to**: "; + } + else if($field['name'] == 'Related to') { + $extra .= "**Related to**: "; + } + else if($field['name'] == 'Duplicate') { + $extra .= "**Duplicate**: "; + } + else if($field['name'] == 'Duplicates') { + $extra .= "**Duplicates**: "; + } + else if($field['name'] == 'Patches') { + $extra .= "**Patches**: "; + } + else if($field['name'] == 'Patch for') { + $extra .= "**Patch for**: "; + } + else { + $extra .= "**" . $field['name'] . "**: " . $field['value'] . "\n"; + continue; + } - if($extra != "") - $description = $extra . "\n" . $description; - - /* subscribers */ - $ccs = array(); - foreach ($mtask->ccs as $mcc) { - if($mcc && $mcc != "" && $mcc != "None") { - $ccuser = lookup_user(dedup_user($mcc)); - if($ccuser) - $ccs[] = $ccuser->getPHID(); - } - } + $value = explode(" ", str_replace("#", "", $field['value'])); + $first = true; + foreach($value as $subvalue) { + if($first) + $first = false; + else + $extra .= " "; - /* we don't check these */ - $projects = array_unique($projects); + $extra .= "T" . $subvalue; + } - /* create task */ - $task = create_task($author, $mtask->id, $title, $projects, - $description, $assign, $mtask->date, $ccs, $priority, $task_type, $extension_type); - - /* create array with all operations */ - $sorted_dates = array(); - $sorted_actions = array(); + $extra .= "\n"; + } - /* files */ - foreach ($mtask->files as $mfile) { - $sorted_dates[] = $mfile->date; - $sorted_actions[] = $mfile; - } + if($extra != "") + $description = $extra . "\n" . $description; + + /* subscribers */ + $ccs = array(); - /* comments */ - foreach ($mtask->comments as $mcomment) { - $sorted_dates[] = $mcomment->date + 1; // couldn't find stable sort, so hack - $sorted_actions[] = $mcomment; - } + if(!$remove_subscribers) { + if(!$close_as_archived) { /* don't notify for dead issues */ + foreach ($mtask->ccs as $mcc) { + if($mcc && $mcc != "" && $mcc != "None") { + $ccuser = lookup_user(dedup_user($mcc)); + if($ccuser) + $ccs[] = $ccuser->getPHID(); + } + } + } + } - /* history */ - $old_status = $status; - $found_last_status = false; + /* we don't check these */ + $projects = array_unique($projects); - foreach ($mtask->history as $mhistory) { - // TODO: different types of status fields exist - if($mhistory->field == "Status" || $mhistory->field == "status_id" || $mhistory->field == "Resolution") { - $sorted_dates[] = $mhistory->date + 2; // couldn't find stable sort, so hack - $sorted_actions[] = array($mhistory->user, $mhistory->date, $old_status); - $old_status = $mhistory->old; - $found_last_status = true; - break; // only does last status, too messy to figure out from history - } - } + /* create task */ + $task = create_task($author, $mtask->id, $title, $projects, + $description, $assign, $mtask->date, $ccs, $priority, $task_type); + + /* create array with all operations */ + $sorted_dates = array(); + $sorted_actions = array(); - if(!$found_last_status) { - $sorted_dates[] = $mtask->date; - $sorted_actions[] = array("None", $mtask->date, $old_status); - } + /* files */ + foreach ($mtask->files as $mfile) { + $sorted_dates[] = $mfile->date; + $sorted_actions[] = $mfile; + } - /* sort and apply in order */ - array_multisort($sorted_dates, $sorted_actions); + /* comments */ + foreach ($mtask->comments as $mcomment) { + $sorted_dates[] = $mcomment->date + 1; // couldn't find stable sort, so hack + $sorted_actions[] = $mcomment; + } - foreach($sorted_actions as $action) { - if(is_object($action) && get_class($action) == "MigrateFile") { - /* create file */ - $mfile = $action; - $user = lookup_user(dedup_user($mfile->user)); + /* history */ + $old_status = $status; + $found_last_status = false; - // TODO skip low file IDS to avoid F1..F12 becoming shortcut key links - // TODO mysql file size limit - if($user) - create_file($task, $user, $mfile->name, $mfile->contents, $mfile->date); - //create_comment($task, $user, "Attach file: " . $mfile->name, $mfile->date); - } - else if(is_object($action) && get_class($action) == "MigrateComment") { - /* create comment */ - $mcomment = $action; - $user = lookup_user(dedup_user($mcomment->user)); - if($user) { - $description = '%%%' . html_entity_decode($mcomment->description) . '%%%'; - create_comment($task, $user, $description, $mcomment->date); - } - } - else { - /* change status */ - $muser = $action[0]; - $mdate = $action[1]; - $mstatus = $action[2]; + foreach ($mtask->history as $mhistory) { + if($mhistory->field == "Status" || $mhistory->field == "status_id" || $mhistory->field == "Resolution") { + $sorted_dates[] = $mhistory->date + 2; // couldn't find stable sort, so hack + $sorted_actions[] = array($mhistory->user, $mhistory->date, $old_status); + $old_status = $mhistory->old; + $found_last_status = true; + break; // only does last status, too messy to figure out from history + } + } - $user = lookup_user(dedup_user($muser)); - if(!$user) - $user = lookup_user("None"); + if(!$found_last_status) { + $sorted_dates[] = $mtask->date; + $sorted_actions[] = array("None", $mtask->date, $old_status); + } - set_status($task, $user, $mstatus, $mdate); - } - } + /* sort and apply in order */ + array_multisort($sorted_dates, $sorted_actions); - /* final status check */ - if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $close_as_archived) - set_status($task, lookup_user("None"), ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED, $mtask->date); + foreach($sorted_actions as $action) { + if(is_object($action) && get_class($action) == "MigrateFile") { + /* create file */ + $mfile = $action; + $user = lookup_user(dedup_user($mfile->user)); - if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $mtask->state == "Closed") - echo "ERROR: status out of sync, task should have been closed (" . $id . ")\n"; + if($user) + create_file($task, $user, $mfile->name, $mfile->contents, $mfile->date); + //create_comment($task, $user, "Attach file: " . $mfile->name, $mfile->date); + } + else if(is_object($action) && get_class($action) == "MigrateComment") { + /* create comment */ + $mcomment = $action; + $user = lookup_user(dedup_user($mcomment->user)); + if($user) { + $description = '%%%' . html_entity_decode($mcomment->description) . '%%%'; + create_comment($task, $user, $description, $mcomment->date); + } + } + else { + /* change status */ + $muser = $action[0]; + $mdate = $action[1]; + $mstatus = $action[2]; + + $user = lookup_user(dedup_user($muser)); + if(!$user) + $user = lookup_user("None"); + + set_status($task, $user, $mstatus, $mdate); + } + } + + /* final status check */ + if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $close_as_archived) + set_status($task, lookup_user("None"), ManiphestTaskStatus::STATUS_CLOSED_ARCHIVED, $mtask->date); + + if($task->getStatus() == ManiphestTaskStatus::STATUS_OPEN && $mtask->state == "Closed") + echo "ERROR: status out of sync, task should have been closed (" . $id . ")\n"; } +// TODO: test importing the whole range of tasks locally + diff --git a/migration/import_users.php b/migration/import_users.php index 35f6866a62..b1b6b4abd7 100755 --- a/migration/import_users.php +++ b/migration/import_users.php @@ -11,8 +11,8 @@ require_once 'phab.php'; function isValidTimezoneId($timezoneId) { - @$tz=timezone_open($timezoneId); - return $tz!==FALSE; + @$tz=timezone_open($timezoneId); + return $tz!==FALSE; } $musers = unserialize(file_get_contents("dump/users")); @@ -21,117 +21,116 @@ $usedemails = array(); foreach ($musers as $muser) { - $username = $muser->name; - $userid = $muser->id; - $realname = trim($muser->realname); - $email = $muser->email; - $date = $muser->date; - $timezone = $muser->timezone; + $username = $muser->name; + $userid = $muser->id; + $realname = trim($muser->realname); + $email = $muser->email; + $date = $muser->date; + $timezone = $muser->timezone; - // TODO broken intentionally to avoid sending emails during tests - $email = "brokenemail___" . $email . "___brokenemail"; + $email = "_tmpdisabledemail_" . $email . "_tmpdisabledemail_"; - /* skip duplicate users */ - if(array_key_exists($username, $migrate_dedup_users)) - continue; + /* skip duplicate users */ + if(array_key_exists($username, $migrate_dedup_users)) + continue; - /* log imported users */ - $importeduser = new MigrateImportedUser(); - $importeduser->name = $username; - $importeduser->email = $email; + /* log imported users */ + $importeduser = new MigrateImportedUser(); + $importeduser->name = $username; + $importeduser->email = $email; - /* detect spam */ - $isspam = false; + /* detect spam */ + $isspam = false; - foreach($spammails as $spam) - if(endsWith($email, $spam)) - $isspam = true; - - if(!$isspam && strlen($realname) > 4) { - if(substr($realname, 0, strlen($realname)-2) == $username . " " . $username) { - if(ctype_upper(substr($realname, strlen($realname)-2, 2))) { - $isspam = true; - } - } - } - - if ($isspam) { - $importeduser->isspam = true; - $importedusers[$username] = $importeduser; - continue; - } + foreach($spammails as $spam) + if(endsWith($email, $spam)) + $isspam = true; + + if(!$isspam && strlen($realname) > 4) { + if(substr($realname, 0, strlen($realname)-2) == $username . " " . $username) { + if(ctype_upper(substr($realname, strlen($realname)-2, 2))) { + $isspam = true; + } + } + } + + if ($isspam) { + $importeduser->isspam = true; + $importedusers[$username] = $importeduser; + continue; + } - /* fix timezones */ - if (!isValidTimezoneId($timezone)) { - switch($timezone) { - case "China/Beijing": $timezone = "Asia/Shanghai"; break; - case "China/Shanghai": $timezone = "Asia/Shanghai"; break; - case "-1": $timezone = "GMT"; break; - case "-2": $timezone = "GMT"; break; - case "-3": $timezone = "GMT"; break; - case "0": $timezone = "GMT"; break; - case "1": $timezone = "GMT"; break; - case "2": $timezone = "GMT"; break; - case "3": $timezone = "GMT"; break; - case "Asia/Beijing": $timezone = "Asia/Shanghai"; break; - case "Asia/Riyadh87": $timezone = "Asia/Riyadh"; break; - case "Asia/Riyadh88": $timezone = "Asia/Riyadh"; break; - case "Asia/Riyadh89": $timezone = "Asia/Riyadh"; break; - case "Mideast/Riyadh87": $timezone = "Asia/Riyadh"; break; - case "Mideast/Riyadh88": $timezone = "Asia/Riyadh"; break; - case "Mideast/Riyadh89": $timezone = "Asia/Riyadh"; break; - } - } + /* fix timezones */ + if (!isValidTimezoneId($timezone)) { + switch($timezone) { + case "China/Beijing": $timezone = "Asia/Shanghai"; break; + case "China/Shanghai": $timezone = "Asia/Shanghai"; break; + case "-1": $timezone = "GMT"; break; + case "-2": $timezone = "GMT"; break; + case "-3": $timezone = "GMT"; break; + case "0": $timezone = "GMT"; break; + case "1": $timezone = "GMT"; break; + case "2": $timezone = "GMT"; break; + case "3": $timezone = "GMT"; break; + case "Asia/Beijing": $timezone = "Asia/Shanghai"; break; + case "Asia/Riyadh87": $timezone = "Asia/Riyadh"; break; + case "Asia/Riyadh88": $timezone = "Asia/Riyadh"; break; + case "Asia/Riyadh89": $timezone = "Asia/Riyadh"; break; + case "Mideast/Riyadh87": $timezone = "Asia/Riyadh"; break; + case "Mideast/Riyadh88": $timezone = "Asia/Riyadh"; break; + case "Mideast/Riyadh89": $timezone = "Asia/Riyadh"; break; + } + } - if (!isValidTimezoneId($timezone)) { - echo "ERROR: invalid timezone " . $timezone . ", changed to GMT\n"; - $timezone = "GMT"; - } - - /* check existing user and email */ - $existing_user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username); - if ($existing_user) { - echo 'ERROR: ' . $username . " already exists.\n"; - } + if (!isValidTimezoneId($timezone)) { + echo "ERROR: invalid timezone " . $timezone . ", changed to GMT\n"; + $timezone = "GMT"; + } + + /* check existing user and email */ + $existing_user = id(new PhabricatorUser())->loadOneWhere('username = %s', $username); + if ($existing_user) { + echo 'ERROR: ' . $username . " already exists.\n"; + } - $existing_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email); - if ($existing_email) { - echo 'ERROR: ' . $email . " already exists for user " . $username . ".\n"; - } + $existing_email = id(new PhabricatorUserEmail())->loadOneWhere('address = %s', $email); + if ($existing_email) { + echo 'ERROR: ' . $email . " already exists for user " . $username . ".\n"; + } - if ($existing_email || $existing_user) { - $importedusers[$username] = $importeduser; - continue; - } + if ($existing_email || $existing_user) { + $importedusers[$username] = $importeduser; + continue; + } - /* create user */ - $user = new PhabricatorUser(); - $user->setUsername($username); - $user->setRealname($realname); - $user->setOverrideDate($date); - $user->setOverrideID($userid); - $user->setTimezoneIdentifier($timezone); + /* create user */ + $user = new PhabricatorUser(); + $user->setUsername($username); + $user->setRealname($realname); + $user->setOverrideDate($date); + $user->setOverrideID($userid); + $user->setTimezoneIdentifier($timezone); - if(in_array($username, $admins)) - $user->setIsAdmin(true); + if(in_array($username, $admins)) + $user->setIsAdmin(true); - $email_object = id(new PhabricatorUserEmail()) - ->setAddress($email) - ->setIsVerified(1); + $email_object = id(new PhabricatorUserEmail()) + ->setAddress($email) + ->setIsVerified(1); - id(new PhabricatorUserEditor()) - ->setActor($user) - ->createNewUser($user, $email_object); + id(new PhabricatorUserEditor()) + ->setActor($user) + ->createNewUser($user, $email_object); - /* set password */ - $envelope = new PhutilOpaqueEnvelope($muser->password); - id(new PhabricatorUserEditor()) - ->setActor($user) - ->changePassword($user, $envelope, true); + /* set password */ + $envelope = new PhutilOpaqueEnvelope($muser->password); + id(new PhabricatorUserEditor()) + ->setActor($user) + ->changePassword($user, $envelope, true); - /* log imported user */ - $importedusers[$username] = $importeduser; - $usedemails[strtolower($email)] = $username; + /* log imported user */ + $importedusers[$username] = $importeduser; + $usedemails[strtolower($email)] = $username; } file_put_contents('dump/importedusers', serialize($importedusers)); diff --git a/migration/migration_steps.txt b/migration/migration_steps.txt new file mode 100644 index 0000000000..87681da6f1 --- /dev/null +++ b/migration/migration_steps.txt @@ -0,0 +1,142 @@ + +A) CONFIGURE PHABRICATOR +======================== + +./bin/config set policy.allow-public true +./bin/config set feed.public true +./bin/config set welcome.file rsrc/custom/static/welcome.html + +set maniphest.custom-field-definitions + +{ + "blender:task-type": { + "name": "Type", + "type": "select", + "search": true, + "options": { + "Bug": "Bug", + "Patch": "Patch", + "Design": "Design", + "To Do": "To Do", + "Feature Request": "Feature Request", + "OpenGL Error": "OpenGL Error" + } + } +} + +set maniphest.priorities + +{ + "100" : { + "name" : "Unbreak Now!", + "short" : "Unbreak!", + "color" : "indigo" + }, + "90" : { + "name" : "Needs Triage", + "short" : "Triage", + "color" : "violet" + }, + "50" : { + "name" : "Confirmed", + "short" : "Confirmed", + "color" : "orange" + }, + "40" : { + "name" : "Normal", + "short" : "Normal", + "color" : "yellow" + }, + "30" : { + "name" : "Incomplete", + "short" : "Incomplete", + "color" : "red" + }, + "20" : { + "name" : "Low", + "short" : "Low", + "color" : "yellow" + } +} + + +Disable irrelevant applications and set policies (TODO figure out policies!) + + +B) FILE STORAGE +=============== + +Set some file storage upload limit (I think projects.blender.org is 5MB, but make it bigger for import to be sure, can lower again later): + +./bin/config set storage.upload-size-limit 10M + + +Decide to store files in MySQL DB or in files on disk. So either: + +./bin/config set storage.local-disk.path /some/path/to/files + +Or increase MySQL storage limit to match storage.upload-size-limit + + +C) MYSQL TABLE TWEAKS +===================== + +Avoid F1, F2 shortcut keys being considered as file links: + +ALTER TABLE phabricator_file.file AUTO_INCREMENT = 1000; + +Avoid conflicts with existing report numbers or users while testing: + +ALTER TABLE phabricator_maniphest.maniphest_task AUTO_INCREMENT = 50000; +ALTER TABLE phabricator_user.user AUTO_INCREMENT = 50000; + + +D) ACCIDENTAL EMAIL SENDING +=========================== + +All email addresses have been modified to avoid sending emails while users and tasks are being created. +Either disable email sending code in phab, or disable postfix, or figure out what happens when you try to send a ton of emails to invalid addresses. + + +E) IMPORT USERS AND PROJECTS +============================ + +./export_users.php on projects.blender.org +copy over dump/ folder +./import_users.php on developer.blender.org + +./import_projects.php + + +F) IMPORT TASKS +=============== + +This is going to be slow and lots of data, best to do it in steps, perhaps starting with the newest reports. + +./export_task.php 37000 38000 +copy over dump/ folder +./import_task.php 37000 38000 + +And so on for all task ranges .. + + +G) TESTS +======== + +* Check if number of developers with commit rights match +* Check if number of open bugs and patches roughly match +* Check for report status, attached files, missing comments, etc +* Add email address to you user settings to test (it's set to an invalid one for testing) +* Test if emails, password reset, etc works + + +H) FOR FINAL +============ + +* Search and remove _tmpdisabledemail_ on all email addresses in DB +* Preserve user and project data from testing period somehow, or dump it all? +* Replace projects.blender.org link in comments (either in DB or beforehand) +* Perhaps clear feeds in DB, may take up unnecessary space? +* Make redirects from projects.blender.org + + diff --git a/migration/phab.php b/migration/phab.php index a51ae69b16..282ea3cfd7 100644 --- a/migration/phab.php +++ b/migration/phab.php @@ -2,140 +2,136 @@ function create_custom_field_transaction($task, $user, $name, $value, $template, $date) { - // TODO: hide transactions for irrelevant fields $field_list = PhabricatorCustomField::getObjectFields($task, PhabricatorCustomField::ROLE_EDIT); foreach ($field_list->getFields() as $field) { - $field->setObject($task); - $field->setViewer($user); - } + $field->setObject($task); + $field->setViewer($user); + } $field_list->readFieldsFromStorage($task); $aux_fields = $field_list->getFields(); - $old_values = array(); - foreach ($aux_fields as $aux_arr_key => $aux_field) { - if($aux_arr_key == "std:maniphest:" . $name) { - $aux_old_value = $aux_field->getOldValueForApplicationTransactions(); - $aux_field->setValueFromStorage($value); - $aux_new_value = $aux_field->getNewValueForApplicationTransactions(); + $old_values = array(); + foreach ($aux_fields as $aux_arr_key => $aux_field) { + if($aux_arr_key == "std:maniphest:" . $name) { + $aux_old_value = $aux_field->getOldValueForApplicationTransactions(); + $aux_field->setValueFromStorage($value); + $aux_new_value = $aux_field->getNewValueForApplicationTransactions(); - $placeholder_editor = new PhabricatorUserProfileEditor(); + $placeholder_editor = new PhabricatorUserProfileEditor(); - $field_errors = $aux_field->validateApplicationTransactions( - $placeholder_editor, - PhabricatorTransactions::TYPE_CUSTOMFIELD, - array( - id(new ManiphestTransaction()) - ->setOldValue($aux_old_value) - ->setNewValue($aux_new_value), - )); + $field_errors = $aux_field->validateApplicationTransactions( + $placeholder_editor, + PhabricatorTransactions::TYPE_CUSTOMFIELD, + array( + id(new ManiphestTransaction()) + ->setOldValue($aux_old_value) + ->setNewValue($aux_new_value), + )); - foreach ($field_errors as $error) { - $errors[] = $error->getMessage(); - } + foreach ($field_errors as $error) { + $errors[] = $error->getMessage(); + } - $old_values[$aux_field->getFieldKey()] = $aux_old_value; - } - } + $old_values[$aux_field->getFieldKey()] = $aux_old_value; + } + } - $transactions = array(); + $transactions = array(); - foreach ($aux_fields as $aux_arr_key => $aux_field) { - if($aux_arr_key == "std:maniphest:" . $name) { - $transaction = clone $template; - $transaction->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD); - $aux_key = $aux_field->getFieldKey(); - $transaction->setMetadataValue('customfield:key', $aux_key); - $old = idx($old_values, $aux_key); - $new = $aux_field->getNewValueForApplicationTransactions(); + foreach ($aux_fields as $aux_arr_key => $aux_field) { + if($aux_arr_key == "std:maniphest:" . $name) { + $transaction = clone $template; + $transaction->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD); + $aux_key = $aux_field->getFieldKey(); + $transaction->setMetadataValue('customfield:key', $aux_key); + $old = idx($old_values, $aux_key); + $new = $aux_field->getNewValueForApplicationTransactions(); - $transaction->setOldValue($old); - $transaction->setNewValue($new); - $transaction->setOverrideDate($date); + $transaction->setOldValue($old); + $transaction->setNewValue($new); + $transaction->setOverrideDate($date); - $transactions[] = $transaction; + // TODO: hide transactions for irrelevant fields + $transactions[] = $transaction; + } + } - // XXX not working! - //$aux_field->applyApplicationTransactionExternalEffects($transaction); - } - } - - return $transactions; + return $transactions; } -function create_task($user, $id, $title, $projects, $description, $assign_user, $date, $ccs, $priority, $type_field, $extension_field) +function create_task($user, $id, $title, $projects, $description, $assign_user, $date, $ccs, $priority, $type_field) { - /* create task */ - $task = ManiphestTask::initializeNewTask($user); - $task->setTitle($title); - $task->setProjectPHIDs($projects); - $task->setCCPHIDs($ccs); - $task->setDescription($description); - $task->setPriority($priority); - $task->setOverrideDate($date); - $task->setOverrideID($id); + /* create task */ + $task = ManiphestTask::initializeNewTask($user); + $task->setTitle($title); + $task->setProjectPHIDs($projects); + $task->setCCPHIDs($ccs); + // TODO when editing a task, it shows the description as edited even though it didn't really happen, why? + $task->setDescription($description); + $task->setPriority($priority); + $task->setOverrideDate($date); + $task->setOverrideID($id); - if ($assign_user) - $task->setOwnerPHID($assign_user->getPHID()); + if ($assign_user) + $task->setOwnerPHID($assign_user->getPHID()); - /* content source */ - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + /* content source */ + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_UNKNOWN, + array()); - /* transactions */ - $changes = array(); - $changes[ManiphestTransaction::TYPE_STATUS] = ManiphestTaskStatus::STATUS_OPEN; - $changes[PhabricatorTransactions::TYPE_VIEW_POLICY] = 'public'; - $changes[PhabricatorTransactions::TYPE_EDIT_POLICY] = 'admin'; // TODO which permission? + /* transactions */ + $changes = array(); + $changes[ManiphestTransaction::TYPE_STATUS] = ManiphestTaskStatus::STATUS_OPEN; + $changes[PhabricatorTransactions::TYPE_VIEW_POLICY] = 'public'; + $changes[PhabricatorTransactions::TYPE_EDIT_POLICY] = 'admin'; // TODO which permission? - $template = new ManiphestTransaction(); + $template = new ManiphestTransaction(); - $transactions = array(); + $transactions = array(); - foreach ($changes as $type => $value) { - $transaction = clone $template; - $transaction->setTransactionType($type); - $transaction->setNewValue($value); - $transaction->setOverrideDate($date); - $transactions[] = $transaction; - } + foreach ($changes as $type => $value) { + $transaction = clone $template; + $transaction->setTransactionType($type); + $transaction->setNewValue($value); + $transaction->setOverrideDate($date); + $transactions[] = $transaction; + } - /* type */ - $transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:task-type", $type_field, $template, $date)); - if($extension_field != "None") - $transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:extension-type", $extension_field, $template, $date)); + /* type */ + $transactions = array_merge($transactions, create_custom_field_transaction($task, $user, "blender:task-type", $type_field, $template, $date)); - $editor = id(new ManiphestTransactionEditor()) - ->setActor($user) - ->setContentSource($content_source) - ->setContinueOnNoEffect(true) - ->applyTransactions($task, $transactions); + $editor = id(new ManiphestTransactionEditor()) + ->setActor($user) + ->setContentSource($content_source) + ->setContinueOnNoEffect(true) + ->applyTransactions($task, $transactions); - return $task; + return $task; } function create_comment($task, $user, $description, $date) { - /* content source */ - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + /* content source */ + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_UNKNOWN, + array()); - /* transactions */ - $comment = id(new ManiphestTransactionComment()); - $comment->setContent($description); + /* transactions */ + $comment = id(new ManiphestTransactionComment()); + $comment->setContent($description); - $transaction = id(new ManiphestTransaction()); - $transaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); - $transaction->setOverrideDate($date); - $transaction->attachComment($comment); + $transaction = id(new ManiphestTransaction()); + $transaction->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); + $transaction->setOverrideDate($date); + $transaction->attachComment($comment); - $transactions = array(); - $transactions[] = $transaction; + $transactions = array(); + $transactions[] = $transaction; - /* apply */ + /* apply */ $editor = id(new ManiphestTransactionEditor()) ->setActor($user) ->setContentSource($content_source) @@ -145,40 +141,40 @@ function create_comment($task, $user, $description, $date) function create_file($task, $user, $name, $contents, $date) { - /* content source */ - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + /* content source */ + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_UNKNOWN, + array()); - /* files */ - $files = array(); + /* files */ + $files = array(); - $file = PhabricatorFile::newFromFileData( - $contents, - array( - 'authorPHID' => $user->getPHID(), - 'name' => $name, - )); - $files[] = $file; + $file = PhabricatorFile::newFromFileData( + $contents, + array( + 'authorPHID' => $user->getPHID(), + 'name' => $name, + )); + $files[] = $file; - $files = mpull($files, 'getPHID', 'getPHID'); - $new = $task->getAttached(); - foreach ($files as $phid) { - if (empty($new[PhabricatorFilePHIDTypeFile::TYPECONST])) { - $new[PhabricatorFilePHIDTypeFile::TYPECONST] = array(); - } + $files = mpull($files, 'getPHID', 'getPHID'); + $new = $task->getAttached(); + foreach ($files as $phid) { + if (empty($new[PhabricatorFilePHIDTypeFile::TYPECONST])) { + $new[PhabricatorFilePHIDTypeFile::TYPECONST] = array(); + } - $new[PhabricatorFilePHIDTypeFile::TYPECONST][$phid] = array(); - } + $new[PhabricatorFilePHIDTypeFile::TYPECONST][$phid] = array(); + } - /* transaction */ - $transaction = new ManiphestTransaction(); - $transaction->setTransactionType(ManiphestTransaction::TYPE_ATTACH); - $transaction->setNewValue($new); - $transaction->setOverrideDate($date); - $transactions[] = $transaction; + /* transaction */ + $transaction = new ManiphestTransaction(); + $transaction->setTransactionType(ManiphestTransaction::TYPE_ATTACH); + $transaction->setNewValue($new); + $transaction->setOverrideDate($date); + $transactions[] = $transaction; - /* apply */ + /* apply */ $editor = id(new ManiphestTransactionEditor()) ->setActor($user) ->setContentSource($content_source) @@ -188,83 +184,83 @@ function create_file($task, $user, $name, $contents, $date) function set_status($task, $user, $status, $date) { - /* content source */ - $content_source = PhabricatorContentSource::newForSource( - PhabricatorContentSource::SOURCE_UNKNOWN, - array()); + /* content source */ + $content_source = PhabricatorContentSource::newForSource( + PhabricatorContentSource::SOURCE_UNKNOWN, + array()); - /* transactions */ - $changes = array(); - $changes[ManiphestTransaction::TYPE_STATUS] = $status; + /* transactions */ + $changes = array(); + $changes[ManiphestTransaction::TYPE_STATUS] = $status; - $template = new ManiphestTransaction(); + $template = new ManiphestTransaction(); - $transactions = array(); + $transactions = array(); - foreach ($changes as $type => $value) { - $transaction = clone $template; - $transaction->setTransactionType($type); - $transaction->setNewValue($value); - $transaction->setOverrideDate($date); - $transactions[] = $transaction; - } + foreach ($changes as $type => $value) { + $transaction = clone $template; + $transaction->setTransactionType($type); + $transaction->setNewValue($value); + $transaction->setOverrideDate($date); + $transactions[] = $transaction; + } - $editor = id(new ManiphestTransactionEditor()) - ->setActor($user) - ->setContentSource($content_source) - ->setContinueOnNoEffect(true) - ->applyTransactions($task, $transactions); + $editor = id(new ManiphestTransactionEditor()) + ->setActor($user) + ->setContentSource($content_source) + ->setContinueOnNoEffect(true) + ->applyTransactions($task, $transactions); } function create_project($name, $username, $active, $membernames, $blurb = '') { - $user = lookup_user($username); + $user = lookup_user($username); - /* create project */ - $project = new PhabricatorProject(); - $project->setAuthorPHID($user->getPHID()); - $project->attachMemberPHIDs(array()); - $profile = new PhabricatorProjectProfile(); + /* create project */ + $project = new PhabricatorProject(); + $project->setAuthorPHID($user->getPHID()); + $project->attachMemberPHIDs(array()); + $profile = new PhabricatorProjectProfile(); - $xactions = array(); + $xactions = array(); - /* policy */ - $project->setViewPolicy("public"); - $project->setEditPolicy("admin"); - $project->setJoinPolicy("admin"); + /* policy */ + $project->setViewPolicy("public"); + $project->setEditPolicy("admin"); + $project->setJoinPolicy("admin"); - /* archived */ - if(!$active) - $project->setStatus(PhabricatorProjectStatus::STATUS_ARCHIVED); - /* name transaction */ - $xaction = new PhabricatorProjectTransaction(); - $xaction->setTransactionType( - PhabricatorProjectTransactionType::TYPE_NAME); - $xaction->setNewValue($name); - $xactions[] = $xaction; + /* archived */ + if(!$active) + $project->setStatus(PhabricatorProjectStatus::STATUS_ARCHIVED); + /* name transaction */ + $xaction = new PhabricatorProjectTransaction(); + $xaction->setTransactionType( + PhabricatorProjectTransaction::TYPE_NAME); + $xaction->setNewValue($name); + $xactions[] = $xaction; - /* members transaction */ - $member_phids = array(); - foreach($membernames as $membername) { - $member_phids[] = lookup_user($membername)->getPHID(); - } + /* members transaction */ + $member_phids = array(); + foreach($membernames as $membername) { + $member_phids[] = lookup_user($membername)->getPHID(); + } - $xaction = new PhabricatorProjectTransaction(); - $xaction->setTransactionType( - PhabricatorProjectTransactionType::TYPE_MEMBERS); - $xaction->setNewValue($member_phids); - $xactions[] = $xaction; + $xaction = new PhabricatorProjectTransaction(); + $xaction->setTransactionType( + PhabricatorProjectTransaction::TYPE_MEMBERS); + $xaction->setNewValue($member_phids); + $xactions[] = $xaction; - /* apply transaction */ - $editor = new PhabricatorProjectEditor($project); - $editor->setActor($user); - $editor->applyTransactions($xactions); + /* apply transaction */ + $editor = new PhabricatorProjectEditor($project); + $editor->setActor($user); + $editor->applyTransactions($xactions); - /* set blurb */ - $profile->setBlurb($blurb); + /* set blurb */ + $profile->setBlurb($blurb); - $project->save(); - $profile->setProjectPHID($project->getPHID()); - $profile->save(); + $project->save(); + $profile->setProjectPHID($project->getPHID()); + $profile->save(); } diff --git a/migration/storage.php b/migration/storage.php index 7b915ad09a..63774b5030 100644 --- a/migration/storage.php +++ b/migration/storage.php @@ -3,97 +3,97 @@ /* serialization */ class MigrateFile { - public $name; - public $contents; - public $user; - public $date; - public $type; + public $name; + public $contents; + public $user; + public $date; + public $type; } class MigrateComment { - public $user; - public $description; - public $date; + public $user; + public $description; + public $date; } class MigrateHistory { - public $user; - public $date; - public $field; - public $old; + public $user; + public $date; + public $field; + public $old; } class MigrateTask { - public $id; - public $author; - public $title; - public $description; - public $date; - public $assign; - public $state; - public $priority; + public $id; + public $author; + public $title; + public $description; + public $date; + public $assign; + public $state; + public $priority; - public $project; - public $tracker; + public $project; + public $tracker; - public $comments = array(); - public $files = array(); - public $ccs = array(); - public $history = array(); + public $comments = array(); + public $files = array(); + public $ccs = array(); + public $history = array(); - public $extra_fields = array(); + public $extra_fields = array(); } class MigrateUser { - public $name; - public $id; - public $realname; - public $email; - public $date; - public $timezone; - public $password; + public $name; + public $id; + public $realname; + public $email; + public $date; + public $timezone; + public $password; } class MigrateImportedUser { - public $name; - public $email; - public $isspam = false; - public $duplicateof = null; + public $name; + public $email; + public $isspam = false; + public $duplicateof = null; } /* utilities */ function startsWith($haystack, $needle) { - return $needle === "" || strpos($haystack, $needle) === 0; + return $needle === "" || strpos($haystack, $needle) === 0; } function endsWith($haystack, $needle) { - return $needle === "" || substr($haystack, -strlen($needle)) === $needle; + return $needle === "" || substr($haystack, -strlen($needle)) === $needle; } function lookup_user($name) { - if($name == null) - return null; + if($name == null) + return null; - $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $name); - if (!$user) - echo "ERROR: lookup of user " . $name . " failed\n"; + $user = id(new PhabricatorUser())->loadOneWhere('username = %s', $name); + if (!$user) + echo "ERROR: lookup of user " . $name . " failed\n"; - return $user; + return $user; } function lookup_project($name) { - if($name == null) - return null; + if($name == null) + return null; - $project = id(new PhabricatorProject())->loadOneWhere('name = %s', $name); - if (!$project) - echo "ERROR: lookup of project " . $name . " failed\n"; + $project = id(new PhabricatorProject())->loadOneWhere('name = %s', $name); + if (!$project) + echo "ERROR: lookup of project " . $name . " failed\n"; - return $project; + return $project; }