diff --git a/resources/sql/patches/repository-lint.sql b/resources/sql/patches/repository-lint.sql new file mode 100644 index 0000000000..f4da747047 --- /dev/null +++ b/resources/sql/patches/repository-lint.sql @@ -0,0 +1,24 @@ +CREATE TABLE {$NAMESPACE}_repository.repository_branch ( + id int unsigned NOT NULL AUTO_INCREMENT, + repositoryID int unsigned NOT NULL, + name varchar(255) NOT NULL, + lintCommit varchar(40), + dateCreated int unsigned NOT NULL, + dateModified int unsigned NOT NULL, + UNIQUE (repositoryID, name), + PRIMARY KEY (id) +); + +CREATE TABLE {$NAMESPACE}_repository.repository_lintmessage ( + id int unsigned NOT NULL AUTO_INCREMENT, + branchID int unsigned NOT NULL, + path varchar(512) NOT NULL, + line int unsigned NOT NULL, + code varchar(32) NOT NULL, + severity varchar(16) NOT NULL, + name varchar(255) NOT NULL, + description text NOT NULL, + INDEX (branchID, path(64)), + INDEX (branchID, code, path(64)), + PRIMARY KEY (id) +); diff --git a/scripts/repository/save_lint.php b/scripts/repository/save_lint.php new file mode 100755 index 0000000000..a4f1ba0ff0 --- /dev/null +++ b/scripts/repository/save_lint.php @@ -0,0 +1,103 @@ +#!/usr/bin/env php +getSourceControlPath()))->getPath(); + +$project_id = $working_copy->getProjectID(); +$project = id(new PhabricatorRepositoryArcanistProject()) + ->loadOneWhere('name = %s', $project_id); +if (!$project || !$project->getRepositoryID()) { + throw new Exception("Couldn't find repository for {$project_id}."); +} + +$branch_name = $api->getBranchName(); +$branch = id(new PhabricatorRepositoryBranch())->loadOneWhere( + 'repositoryID = %d AND name = %s', + $project->getRepositoryID(), + $branch_name); +if (!$branch) { + $branch = id(new PhabricatorRepositoryBranch()) + ->setRepositoryID($project->getRepositoryID()) + ->setName($branch_name); +} +$branch->setLintCommit($api->getWorkingCopyRevision()); +$branch->save(); +$conn = $branch->establishConnection('w'); + +$inserts = array(); + +while ($json = fgets(STDIN)) { + $paths = json_decode(rtrim($json, "\n"), true); + if (!is_array($paths)) { + throw new Exception("Invalid JSON: {$json}"); + } + + if (!$paths) { + continue; + } + + $conn->openTransaction(); + + foreach (array_chunk(array_keys($paths), 1024) as $some_paths) { + $full_paths = array(); + foreach ($some_paths as $path) { + $full_paths[] = $svn_root.'/'.$path; + } + queryfx( + $conn, + 'DELETE FROM %T WHERE branchID = %d AND path IN (%Ls)', + PhabricatorRepository::TABLE_LINTMESSAGE, + $branch->getID(), + $full_paths); + } + + foreach ($paths as $path => $messages) { + // TODO: Handle multiple $json for a single path. Don't save duplicates. + + foreach ($messages as $message) { + $inserts[] = qsprintf( + $conn, + '(%d, %s, %d, %s, %s, %s, %s)', + $branch->getID(), + $svn_root.'/'.$path, + idx($message, 'line', 0), + idx($message, 'code', ''), + idx($message, 'severity', ''), + idx($message, 'name', ''), + idx($message, 'description', '')); + + if (count($inserts) >= 256) { + save_lint_messages($conn, $inserts); + $inserts = array(); + } + } + } + + $conn->saveTransaction(); +} + +save_lint_messages($conn, $inserts); + +function save_lint_messages($conn, array $inserts) { + if ($inserts) { + queryfx( + $conn, + 'INSERT INTO %T + (branchID, path, line, code, severity, name, description) + VALUES %Q', + PhabricatorRepository::TABLE_LINTMESSAGE, + implode(', ', $inserts)); + } +} diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 4bf8b5aa82..ba43310a68 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -992,6 +992,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryArcanistProjectDeleteController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectDeleteController.php', 'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectEditController.php', 'PhabricatorRepositoryAuditRequest' => 'applications/repository/storage/PhabricatorRepositoryAuditRequest.php', + 'PhabricatorRepositoryBranch' => 'applications/repository/storage/PhabricatorRepositoryBranch.php', 'PhabricatorRepositoryCommit' => 'applications/repository/storage/PhabricatorRepositoryCommit.php', 'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php', 'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php', @@ -2175,6 +2176,7 @@ phutil_register_library_map(array( 'PhabricatorRepositoryArcanistProjectDeleteController' => 'PhabricatorRepositoryController', 'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController', 'PhabricatorRepositoryAuditRequest' => 'PhabricatorRepositoryDAO', + 'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryCommit' => 'PhabricatorRepositoryDAO', 'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker', 'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO', diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 6cf78c842e..c2301df0b1 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -10,6 +10,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO { const TABLE_FILESYSTEM = 'repository_filesystem'; const TABLE_SUMMARY = 'repository_summary'; const TABLE_BADCOMMIT = 'repository_badcommit'; + const TABLE_LINTMESSAGE = 'repository_lintmessage'; protected $phid; protected $name; diff --git a/src/applications/repository/storage/PhabricatorRepositoryBranch.php b/src/applications/repository/storage/PhabricatorRepositoryBranch.php new file mode 100644 index 0000000000..33e3ab24a6 --- /dev/null +++ b/src/applications/repository/storage/PhabricatorRepositoryBranch.php @@ -0,0 +1,9 @@ + 'sql', 'name' => $this->getPatchPath('dropfileproxyimage.sql'), ), + 'repository-lint.sql' => array( + 'type' => 'sql', + 'name' => $this->getPatchPath('repository-lint.sql'), + ), ); }