diff --git a/static/css/directives/ui/build-log-command.css b/static/css/directives/ui/build-log-command.css
new file mode 100644
index 000000000..ebb5abd4c
--- /dev/null
+++ b/static/css/directives/ui/build-log-command.css
@@ -0,0 +1,16 @@
+.build-log-command-element.multistep-seperator {
+ margin-top: 10px;
+ padding-top: 10px;
+ border-top: 1px solid #666;
+}
+
+.build-log-command-element .from-name {
+ position: absolute;
+ top: 3px;
+ left: 22px;
+ background-color: #263945;
+ display: inline-block;
+ color: #aaa;
+ font-size: 12px;
+ padding-right: 10px;
+}
diff --git a/static/css/directives/ui/build-logs-view.css b/static/css/directives/ui/build-logs-view.css
index e4da34a65..92c352872 100644
--- a/static/css/directives/ui/build-logs-view.css
+++ b/static/css/directives/ui/build-logs-view.css
@@ -87,16 +87,15 @@
.build-logs-view .container-header .label {
padding-top: 4px;
text-align: right;
- margin-right: 4px;
+ margin-left: 2px;
+ margin-right: 10px;
width: 86px;
display: inline-block;
border-right: 4px solid #aaa;
background-color: #717171;
- position: absolute;
- top: 4px;
- left: 24px;
+ position: relative;
}
.build-logs-view .dockerfile-command {
@@ -112,10 +111,6 @@
padding-left: 20px;
}
-.build-logs-view .container-header .container-content.build-log-command {
- padding-left: 120px;
-}
-
.build-logs-view .log-entry {
position: relative;
}
diff --git a/static/css/directives/ui/image-info-sidebar.css b/static/css/directives/ui/image-info-sidebar.css
deleted file mode 100644
index 5dffade2b..000000000
--- a/static/css/directives/ui/image-info-sidebar.css
+++ /dev/null
@@ -1,68 +0,0 @@
-.image-info-sidebar .image-comment {
- margin-bottom: 4px;
-}
-
-.image-info-sidebar .image-section {
- margin-top: 12px;
- padding-bottom: 2px;
- position: relative;
-}
-
-.image-info-sidebar .image-section .tag {
- margin: 2px;
- border-radius: 8px;
- display: inline-block;
- padding: 4px;
-}
-
-.image-info-sidebar .image-section .section-icon {
- float: left;
- font-size: 16px;
- margin-left: -4px;
- margin-right: 14px;
- color: #bbb;
- width: 18px;
- text-align: center;
- padding-top: 6px;
-}
-
-.image-info-sidebar .image-section .section-info {
- padding: 4px;
- padding-left: 6px;
- -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.05);
- box-shadow: inset 0 1px 1px rgba(0,0,0,0.05);
- background-color: #f5f5f5;
-
- vertical-align: middle;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.image-info-sidebar .image-section .section-info-with-dropdown {
- padding-right: 30px;
-}
-
-.image-info-sidebar .image-section .dropdown {
- display: inline-block;
- position: absolute;
- top: 0px;
- bottom: 2px;
- right: 0px;
-}
-
-.image-info-sidebar .image-section .dropdown-button {
- position: absolute;
- right: 0px;
- top: 0px;
- bottom: 0px;
-
- background: white;
- padding: 4px;
- padding-left: 8px;
- padding-right: 8px;
- border: 1px solid #eee;
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
- cursor: pointer;
-}
diff --git a/static/css/quay.css b/static/css/quay.css
index ce983fb9b..755e189bb 100644
--- a/static/css/quay.css
+++ b/static/css/quay.css
@@ -222,49 +222,6 @@
font-size: 18px;
}
-.dockerfile-view {
- margin-top: 10px;
- margin: 20px;
- padding: 20px;
- background: #F7F6F6;
- border: 1px solid #ddd;
-}
-
-.dockerfile-view .entry {
- font-family: Consolas, "Lucida Console", Monaco, monospace;
-}
-
-.dockerfile-view .entry.comment {
- color: rgb(82, 172, 82);
-}
-
-.dockerfile-command {
- position: relative;
-}
-
-.dockerfile-command .command-title {
- font-family: Consolas, "Lucida Console", Monaco, monospace;
- padding-left: 90px;
- display: inline-block;
-}
-
-.dockerfile-command .label {
- color: white;
-
- padding-top: 4px;
- text-align: right;
- margin-right: 4px;
- width: 86px;
- display: inline-block;
-
- border-right: 4px solid #aaa;
- background-color: #333;
-
- position: absolute;
- top: 0px;
- left: -4px;
-}
-
.codetooltipcontainer .tooltip-inner {
white-space:pre;
max-width:none;
@@ -2968,26 +2925,6 @@ pre.command:before {
margin: 10px;
}
-.label.FROM {
- border-color: #5bc0de !important;
-}
-
-.label.CMD, .label.EXPOSE, .label.ENTRYPOINT {
- border-color: #428bca !important;
-}
-
-.label.RUN, .label.ADD {
- border-color: #5cb85c !important;
-}
-
-.label.ENV, .label.VOLUME, .label.USER, .label.WORKDIR {
- border-color: #f0ad4e !important;
-}
-
-.label.MAINTAINER {
- border-color: #aaa !important;
-}
-
.dropdown-select {
margin: 10px;
position: relative;
diff --git a/static/directives/build-log-command.html b/static/directives/build-log-command.html
index 40d1c8880..fda7c9ee8 100644
--- a/static/directives/build-log-command.html
+++ b/static/directives/build-log-command.html
@@ -1 +1,4 @@
-
+
+ {{ ::fromName(command.message) }}
+
+
diff --git a/static/directives/dockerfile-command.html b/static/directives/dockerfile-command.html
deleted file mode 100644
index 0e0c7bc5e..000000000
--- a/static/directives/dockerfile-command.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
diff --git a/static/directives/dockerfile-view.html b/static/directives/dockerfile-view.html
deleted file mode 100644
index d1cb834d6..000000000
--- a/static/directives/dockerfile-view.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
- {{ line.text || ' ' }}
-
-
-
-
diff --git a/static/directives/image-feature-view.html b/static/directives/image-feature-view.html
index d6b524844..3ae932275 100644
--- a/static/directives/image-feature-view.html
+++ b/static/directives/image-feature-view.html
@@ -164,9 +164,7 @@
-
-
-
+
diff --git a/static/directives/image-info-sidebar.html b/static/directives/image-info-sidebar.html
deleted file mode 100644
index fe32591d7..000000000
--- a/static/directives/image-info-sidebar.html
+++ /dev/null
@@ -1,94 +0,0 @@
-
diff --git a/static/directives/image-view-layer.html b/static/directives/image-view-layer.html
index 0d0601b6d..23369587e 100644
--- a/static/directives/image-view-layer.html
+++ b/static/directives/image-view-layer.html
@@ -5,9 +5,7 @@
- {{ image.command.join(' ') }}
-
+
diff --git a/static/directives/image-vulnerability-view.html b/static/directives/image-vulnerability-view.html
index bc3e3f4f4..3f127b3cf 100644
--- a/static/directives/image-vulnerability-view.html
+++ b/static/directives/image-vulnerability-view.html
@@ -152,9 +152,7 @@
|
-
-
-
+
diff --git a/static/js/directives/ui/build-log-command.js b/static/js/directives/ui/build-log-command.js
index 68300cda8..acc219b05 100644
--- a/static/js/directives/ui/build-log-command.js
+++ b/static/js/directives/ui/build-log-command.js
@@ -9,7 +9,7 @@ angular.module('quay').directive('buildLogCommand', function () {
transclude: false,
restrict: 'C',
scope: {
- 'command': '=command'
+ 'command': ' ' + title + '';
- }
- };
-
- $scope.getCommandKind = function(title) {
- var space = title.indexOf(' ');
- return title.substring(0, space);
- };
-
- $scope.getCommandTitleHtml = function(title) {
- var space = title.indexOf(' ');
- if (space <= 0) {
- return UtilService.textToSafeHtml(title);
- }
-
- var kind = $scope.getCommandKind(title);
- var sanitized = UtilService.textToSafeHtml(title.substring(space + 1));
-
- var handler = kindHandlers[kind || ''];
- if (handler) {
- return handler(sanitized);
- } else {
- return sanitized;
- }
- };
- }
- };
- return directiveDefinitionObject;
-});
\ No newline at end of file
diff --git a/static/js/directives/ui/dockerfile-command/dockerfile-command.component.css b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.css
new file mode 100644
index 000000000..89ce18853
--- /dev/null
+++ b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.css
@@ -0,0 +1,59 @@
+.label.FROM {
+ border-color: #5bc0de !important;
+}
+
+.label.ARG {
+ border-color: #eaef4d !important;
+}
+
+.label.ONBUILD {
+ border-color: #6813d8 !important;
+}
+
+.label.CMD, .label.EXPOSE, .label.ENTRYPOINT {
+ border-color: #428bca !important;
+}
+
+.label.RUN, .label.ADD, .label.COPY {
+ border-color: #5cb85c !important;
+}
+
+.label.ENV, .label.VOLUME, .label.USER, .label.WORKDIR, .label.HEALTHCHECK, .label.STOPSIGNAL, .label.SHELL {
+ border-color: #f0ad4e !important;
+}
+
+.label.MAINTAINER {
+ border-color: #aaa !important;
+}
+
+.dockerfile-command {
+ position: relative;
+}
+
+.dockerfile-command .command-title {
+ font-family: Consolas, "Lucida Console", Monaco, monospace !important;
+ padding-left: 90px;
+ display: inline-block;
+}
+
+.dockerfile-command .command-title a {
+ color: #5bc0de;
+ font-size: 15px;
+}
+
+.dockerfile-command .label {
+ color: white;
+
+ padding-top: 4px;
+ text-align: right;
+ margin-right: 4px;
+ width: 86px;
+ display: inline-block;
+
+ border-right: 4px solid #aaa;
+ background-color: #333;
+
+ position: absolute;
+ top: 0px;
+ left: -4px;
+}
diff --git a/static/js/directives/ui/dockerfile-command/dockerfile-command.component.html b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.html
new file mode 100644
index 000000000..31003882a
--- /dev/null
+++ b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.html
@@ -0,0 +1,7 @@
+
+
+ {{ ::$ctrl.getCommandKind($ctrl.command) }}
+
+
+
diff --git a/static/js/directives/ui/dockerfile-command/dockerfile-command.component.ts b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.ts
new file mode 100644
index 000000000..5a77f60d0
--- /dev/null
+++ b/static/js/directives/ui/dockerfile-command/dockerfile-command.component.ts
@@ -0,0 +1,73 @@
+import { Input, Component, Inject } from 'ng-metadata/core';
+import './dockerfile-command.component.css';
+
+/**
+ * A component which displays a Dockerfile command, nicely formatted.
+ */
+@Component({
+ selector: 'dockerfile-command',
+ templateUrl: '/static/js/directives/ui/dockerfile-command/dockerfile-command.component.html',
+})
+export class DockerfileCommandComponent {
+ @Input('<') public command: string;
+
+ private registryHandlers: {[domain: string]: Function};
+
+ constructor (@Inject('Config') Config: any, @Inject('UtilService') private utilService: any) {
+ var registryHandlers = {
+ 'quay.io': function(pieces) {
+ var rnamespace = pieces[pieces.length - 2];
+ var rname = pieces[pieces.length - 1].split(':')[0];
+ return '/repository/' + rnamespace + '/' + rname + '/';
+ },
+
+ '': function(pieces) {
+ var rnamespace = pieces.length == 1 ? '_' : 'u/' + pieces[0];
+ var rname = pieces[pieces.length - 1].split(':')[0];
+ return 'https://registry.hub.docker.com/' + rnamespace + '/' + rname + '/';
+ }
+ };
+
+ registryHandlers[Config.getDomain()] = registryHandlers['quay.io'];
+ this.registryHandlers = registryHandlers;
+ }
+
+ private getCommandKind(command: string): string {
+ if (!command) { return ''; }
+
+ var space = command.indexOf(' ');
+ return command.substring(0, space);
+ }
+
+ private getCommandTitleHtml(command: string): string {
+ if (!command) { return ''; }
+
+ var kindHandlers = {
+ 'FROM': (command) => {
+ var parts = command.split(' ');
+ var pieces = parts[0].split('/');
+ var registry = pieces.length < 3 ? '' : pieces[0];
+ if (!this.registryHandlers[registry]) {
+ return command;
+ }
+
+ return '' + parts[0] + ' ' + (parts.splice(1).join(' '));
+ }
+ };
+
+ var space = command.indexOf(' ');
+ if (space <= 0) {
+ return this.utilService.textToSafeHtml(command);
+ }
+
+ var kind = this.getCommandKind(command);
+ var sanitized = this.utilService.textToSafeHtml(command.substring(space + 1));
+
+ var handler = kindHandlers[kind || ''];
+ if (handler) {
+ return handler(sanitized);
+ } else {
+ return sanitized;
+ }
+ }
+}
diff --git a/static/js/directives/ui/dockerfile-view.js b/static/js/directives/ui/dockerfile-view.js
deleted file mode 100644
index d391c8d23..000000000
--- a/static/js/directives/ui/dockerfile-view.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * An element which displays the contents of a Dockerfile in a nicely formatted way.
- */
-angular.module('quay').directive('dockerfileView', function () {
- var directiveDefinitionObject = {
- priority: 0,
- templateUrl: '/static/directives/dockerfile-view.html',
- replace: false,
- transclude: false,
- restrict: 'C',
- scope: {
- 'contents': '=contents'
- },
- controller: function($scope, $element, UtilService) {
- $scope.$watch('contents', function(contents) {
- $scope.lines = [];
-
- var lines = contents ? contents.split('\n') : [];
- for (var i = 0; i < lines.length; ++i) {
- var line = $.trim(lines[i]);
- var kind = 'text';
- if (line && line[0] == '#') {
- kind = 'comment';
- } else if (line.match(/^([A-Z]+\s)/)) {
- kind = 'command';
- }
-
- var lineInfo = {
- 'text': line,
- 'kind': kind
- };
- $scope.lines.push(lineInfo);
- }
- });
- }
- };
- return directiveDefinitionObject;
-});
\ No newline at end of file
diff --git a/static/js/directives/ui/image-command/image-command.component.html b/static/js/directives/ui/image-command/image-command.component.html
new file mode 100644
index 000000000..cce451dfd
--- /dev/null
+++ b/static/js/directives/ui/image-command/image-command.component.html
@@ -0,0 +1,5 @@
+
+ {{ ::$ctrl.command.join(' ') }}
+
+
\ No newline at end of file
diff --git a/static/js/directives/ui/image-command/image-command.component.ts b/static/js/directives/ui/image-command/image-command.component.ts
new file mode 100644
index 000000000..fc55b4f1d
--- /dev/null
+++ b/static/js/directives/ui/image-command/image-command.component.ts
@@ -0,0 +1,26 @@
+import { Input, Component, Inject } from 'ng-metadata/core';
+
+/**
+ * A component which displays an image's command, nicely formatted.
+ */
+@Component({
+ selector: 'image-command',
+ templateUrl: '/static/js/directives/ui/image-command/image-command.component.html',
+})
+export class ImageCommandComponent {
+ @Input('<') public command: string;
+
+ private getDockerfileCommand(command: string[]): string {
+ if (!command || !command.length) { return ''; }
+ command = command.join(' ').split(' ');
+
+ // ["/bin/sh", "-c", "#(nop)", "RUN", "foo"]
+ if (command[0] != '/bin/sh' || command[1] != '-c') { return ''; }
+
+ if (command[2].trim() != '#(nop)') {
+ return 'RUN ' + command.slice(2).join(' ');
+ }
+
+ return command.slice(3).join(' ');
+ };
+}
diff --git a/static/js/directives/ui/image-feature-view.js b/static/js/directives/ui/image-feature-view.js
index efaefc9eb..f9bda9624 100644
--- a/static/js/directives/ui/image-feature-view.js
+++ b/static/js/directives/ui/image-feature-view.js
@@ -13,7 +13,7 @@ angular.module('quay').directive('imageFeatureView', function () {
'image': '=image',
'isEnabled': '=isEnabled'
},
- controller: function($scope, $element, Config, ApiService, VulnerabilityService, ViewArray, ImageMetadataService, TableService) {
+ controller: function($scope, $element, Config, ApiService, VulnerabilityService, ViewArray, TableService) {
$scope.options = {
'filter': null,
'predicate': 'fixableScore',
diff --git a/static/js/directives/ui/image-info-sidebar.js b/static/js/directives/ui/image-info-sidebar.js
deleted file mode 100644
index 2614a5f15..000000000
--- a/static/js/directives/ui/image-info-sidebar.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * An element which displays sidebar information for a image. Primarily used in the repo view.
- */
-angular.module('quay').directive('imageInfoSidebar', function () {
- var directiveDefinitionObject = {
- priority: 0,
- templateUrl: '/static/directives/image-info-sidebar.html',
- replace: false,
- transclude: true,
- restrict: 'C',
- scope: {
- 'tracker': '=tracker',
- 'image': '=image',
- 'imageLoader': '=imageLoader',
-
- 'tagSelected': '&tagSelected',
- 'addTagRequested': '&addTagRequested'
- },
- controller: function($scope, $element, ImageMetadataService) {
- $scope.$watch('image', function(image) {
- if (!image || !$scope.tracker) { return; }
- $scope.imageData = $scope.tracker.lookupImage(image);
- });
-
- $scope.parseDate = function(dateString) {
- return Date.parse(dateString);
- };
-
- $scope.getTags = function(imageData) {
- return $scope.imageLoader.getTagsForImage(imageData);
- };
-
- $scope.getFormattedCommand = ImageMetadataService.getFormattedCommand;
- }
- };
- return directiveDefinitionObject;
-});
\ No newline at end of file
diff --git a/static/js/directives/ui/image-view-layer.js b/static/js/directives/ui/image-view-layer.js
index 1c9b31818..731e42284 100644
--- a/static/js/directives/ui/image-view-layer.js
+++ b/static/js/directives/ui/image-view-layer.js
@@ -13,9 +13,7 @@ angular.module('quay').directive('imageViewLayer', function () {
'image': '=image',
'images': '=images'
},
- controller: function($scope, $element, ImageMetadataService) {
- $scope.getDockerfileCommand = ImageMetadataService.getDockerfileCommand;
-
+ controller: function($scope, $element) {
$scope.getClass = function() {
var index = $.inArray($scope.image, $scope.images);
if (index < 0) {
diff --git a/static/js/directives/ui/image-vulnerability-view.js b/static/js/directives/ui/image-vulnerability-view.js
index be4f6fd81..a0b312fc1 100644
--- a/static/js/directives/ui/image-vulnerability-view.js
+++ b/static/js/directives/ui/image-vulnerability-view.js
@@ -13,7 +13,7 @@ angular.module('quay').directive('imageVulnerabilityView', function () {
'image': '=image',
'isEnabled': '=isEnabled'
},
- controller: function($scope, $element, $routeParams, Config, ApiService, VulnerabilityService, ViewArray, ImageMetadataService, TableService) {
+ controller: function($scope, $element, $routeParams, Config, ApiService, VulnerabilityService, ViewArray, TableService) {
$scope.options = {
'filter': null,
'fixableVulns': $routeParams['fixable'] == 'true',
diff --git a/static/js/quay.module.ts b/static/js/quay.module.ts
index 5051db381..07f697bd7 100644
--- a/static/js/quay.module.ts
+++ b/static/js/quay.module.ts
@@ -29,6 +29,8 @@ import { MarkdownInputComponent } from './directives/ui/markdown/markdown-input.
import { MarkdownViewComponent } from './directives/ui/markdown/markdown-view.component';
import { MarkdownToolbarComponent } from './directives/ui/markdown/markdown-toolbar.component';
import { MarkdownEditorComponent } from './directives/ui/markdown/markdown-editor.component';
+import { DockerfileCommandComponent } from './directives/ui/dockerfile-command/dockerfile-command.component';
+import { ImageCommandComponent } from './directives/ui/image-command/image-command.component';
import { BrowserPlatform, browserPlatform } from './constants/platform.constant';
import { ManageTriggerComponent } from './directives/ui/manage-trigger/manage-trigger.component';
import { ClipboardCopyDirective } from './directives/ui/clipboard-copy/clipboard-copy.directive';
@@ -68,6 +70,8 @@ import * as Clipboard from 'clipboard';
MarkdownToolbarComponent,
MarkdownEditorComponent,
SearchBoxComponent,
+ DockerfileCommandComponent,
+ ImageCommandComponent,
TypeaheadDirective,
ManageTriggerComponent,
ClipboardCopyDirective,
diff --git a/static/js/services/image-metadata-service.js b/static/js/services/image-metadata-service.js
index 4b7d251ed..a4034530a 100644
--- a/static/js/services/image-metadata-service.js
+++ b/static/js/services/image-metadata-service.js
@@ -1,28 +1,8 @@
/**
* Helper service for returning information extracted from repository image metadata.
*/
-angular.module('quay').factory('ImageMetadataService', ['UtilService', function(UtilService) {
+angular.module('quay').factory('ImageMetadataService', [function() {
var metadataService = {};
- metadataService.getFormattedCommand = function(image) {
- if (!image || !image.command || !image.command.length) {
- return '';
- }
-
- var getCommandStr = function(command) {
- // Handle /bin/sh commands specially.
- if (command.length > 2 && command[0] == '/bin/sh' && command[1] == '-c') {
- return command[2];
- }
-
- return command.join(' ');
- };
-
- return getCommandStr(image.command);
- };
-
- metadataService.getEscapedFormattedCommand = function(image) {
- return UtilService.textToSafeHtml(metadataService.getFormattedCommand(image));
- };
metadataService.getImageCommand = function(image, imageId) {
if (!image) {
@@ -44,22 +24,7 @@ angular.module('quay').factory('ImageMetadataService', ['UtilService', function(
return null;
}
- return metadataService.getDockerfileCommand(found.command);
- };
-
- metadataService.getDockerfileCommand = function(command) {
- if (!command) { return ''; }
- command = command.join(' ').split(' ');
-
- // ["/bin/sh", "-c", "#(nop)", "RUN", "foo"]
- if (command[0] != '/bin/sh' || command[1] != '-c') { return ''; }
-
- var commandPrefix = '#(nop)';
- if (command[2] != commandPrefix) {
- return 'RUN ' + command.slice(2).join(' ');
- }
-
- return command.slice(3).join(' ');
+ return found.command;
};
return metadataService;
|