diff --git a/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php b/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php index 50b17523ca..4b36ba83d9 100644 --- a/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildLogRenderController.php @@ -105,7 +105,13 @@ final class HarbormasterBuildLogRenderController $reads = $this->mergeOverlappingReads($reads); foreach ($reads as $key => $read) { - $data = $log->loadData($read['fetchOffset'], $read['fetchLength']); + $fetch_offset = $read['fetchOffset']; + $fetch_length = $read['fetchLength']; + if ($fetch_offset + $fetch_length > $log_size) { + $fetch_length = $log_size - $fetch_offset; + } + + $data = $log->loadData($fetch_offset, $fetch_length); $offset = $read['fetchOffset']; $line = $read['fetchLine']; diff --git a/src/applications/harbormaster/controller/HarbormasterBuildLogViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildLogViewController.php index 41f2aef8e5..40641795c5 100644 --- a/src/applications/harbormaster/controller/HarbormasterBuildLogViewController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildLogViewController.php @@ -16,6 +16,9 @@ final class HarbormasterBuildLogViewController return new Aphront404Response(); } + $target = $log->getBuildTarget(); + $build = $target->getBuild(); + $page_title = pht('Build Log %d', $log->getID()); $log_view = id(new HarbormasterBuildLogView()) @@ -25,6 +28,9 @@ final class HarbormasterBuildLogViewController $crumbs = $this->buildApplicationCrumbs() ->addTextCrumb(pht('Build Logs')) + ->addTextCrumb( + pht('Build %d', $build->getID()), + $build->getURI()) ->addTextCrumb($page_title) ->setBorder(true); diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php index 4507139d47..0e09b4d658 100644 --- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php @@ -363,12 +363,19 @@ final class HarbormasterBuildViewController $log_view->setLines($lines); $log_view->setStart($start); + $prototype_view = id(new PHUIButtonView()) + ->setTag('a') + ->setHref($log->getURI()) + ->setIcon('fa-file-text-o') + ->setText(pht('New View (Prototype)')); + $header = id(new PHUIHeaderView()) ->setHeader(pht( 'Build Log %d (%s - %s)', $log->getID(), $log->getLogSource(), $log->getLogType())) + ->addActionLink($prototype_view) ->setSubheader($this->createLogHeader($build, $log)) ->setUser($viewer); diff --git a/src/applications/harbormaster/view/HarbormasterBuildLogView.php b/src/applications/harbormaster/view/HarbormasterBuildLogView.php index 81705f3f49..e240aab510 100644 --- a/src/applications/harbormaster/view/HarbormasterBuildLogView.php +++ b/src/applications/harbormaster/view/HarbormasterBuildLogView.php @@ -44,28 +44,43 @@ final class HarbormasterBuildLogView extends AphrontView { $header->addActionLink($download_button); - $content_id = celerity_generate_unique_node_id(); - $content_div = javelin_tag( - 'div', - array( - 'id' => $content_id, - 'class' => 'harbormaster-log-view-loading', - ), - pht('Loading...')); - - require_celerity_resource('harbormaster-css'); - - Javelin::initBehavior( - 'harbormaster-log', - array( - 'contentNodeID' => $content_id, - 'renderURI' => $log->getRenderURI($this->getHighlightedLineRange()), - )); - $box_view = id(new PHUIObjectBoxView()) ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setHeader($header) - ->appendChild($content_div); + ->setHeader($header); + + $has_linemap = $log->getLineMap(); + if ($has_linemap) { + $content_id = celerity_generate_unique_node_id(); + $content_div = javelin_tag( + 'div', + array( + 'id' => $content_id, + 'class' => 'harbormaster-log-view-loading', + ), + pht('Loading...')); + + require_celerity_resource('harbormaster-css'); + + Javelin::initBehavior( + 'harbormaster-log', + array( + 'contentNodeID' => $content_id, + 'renderURI' => $log->getRenderURI($this->getHighlightedLineRange()), + )); + + $box_view->appendChild($content_div); + } else { + $box_view->setFormErrors( + array( + pht( + 'This older log is missing required rendering data. To rebuild '. + 'rendering data, run: %s', + phutil_tag( + 'tt', + array(), + '$ bin/harbormaster rebuild-log --force --id '.$log->getID())), + )); + } return $box_view; }