1 import { Component, ViewEncapsulation, AfterViewChecked, ElementRef, ViewChild, OnInit, Input } from '@angular/core';
2 import { Observable } from 'rxjs/Observable';
3 import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms';
4 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
6 import 'rxjs/add/operator/scan';
7 import 'rxjs/add/operator/startWith';
9 import { BuildSettingsModalComponent } from './build-settings-modal/build-settings-modal.component';
11 import { XDSAgentService, ICmdOutput } from '../../@core-xds/services/xdsagent.service';
12 import { ProjectService, IProject } from '../../@core-xds/services/project.service';
13 import { AlertService, IAlert } from '../../@core-xds/services/alert.service';
14 import { SdkService } from '../../@core-xds/services/sdk.service';
17 selector: 'xds-panel-build',
18 templateUrl: './build.component.html',
19 styleUrls: ['./build.component.scss'],
20 encapsulation: ViewEncapsulation.None,
23 export class BuildComponent implements OnInit, AfterViewChecked {
24 @ViewChild('scrollOutput') private scrollContainer: ElementRef;
26 // FIXME workaround of https://github.com/angular/angular-cli/issues/2034
27 // should be removed with angular 5
28 // @Input() curProject: IProject;
29 @Input() curProject = <IProject>null;
31 public buildIsCollapsed = false;
32 public cmdOutput: string;
33 public cmdInfo: string;
34 public curPrj: IProject;
36 private startTime: Map<string, number> = new Map<string, number>();
39 private prjSvr: ProjectService,
40 private xdsSvr: XDSAgentService,
41 private alertSvr: AlertService,
42 private sdkSvr: SdkService,
43 private modalService: NgbModal,
46 this.cmdInfo = ''; // TODO: to be remove (only for debug)
50 // Retreive current project
51 this.prjSvr.curProject$.subscribe(p => this.curPrj = p);
53 // Command output data tunneling
54 this.xdsSvr.CmdOutput$.subscribe(data => {
55 this.cmdOutput += data.stdout;
56 this.cmdOutput += data.stderr;
60 this.xdsSvr.CmdExit$.subscribe(exit => {
61 if (this.startTime.has(exit.cmdID)) {
62 this.cmdInfo = 'Last command duration: ' + this._computeTime(this.startTime.get(exit.cmdID));
63 this.startTime.delete(exit.cmdID);
66 if (exit && exit.code !== 0) {
67 this.cmdOutput += '--- Command exited with code ' + exit.code + ' ---\n\n';
71 this._scrollToBottom();
74 ngAfterViewChecked() {
75 this._scrollToBottom();
82 isSetupValid(): boolean {
83 return (typeof this.curPrj !== 'undefined');
87 if (!this.isSetupValid()) {
88 return this.alertSvr.warning('Please select first a valid project.', true);
91 const activeModal = this.modalService.open(BuildSettingsModalComponent, { size: 'lg', container: 'nb-layout' });
92 activeModal.componentInstance.modalHeader = 'Large Modal';
96 if (!this.isSetupValid()) {
97 return this.alertSvr.warning('Please select first a valid project.', true);
100 this.curPrj.uiSettings.cmdClean,
101 this.curPrj.uiSettings.subpath,
103 this.curPrj.uiSettings.envVars.join(' '));
107 if (!this.isSetupValid()) {
108 return this.alertSvr.warning('Please select first a valid project.', true);
111 this.curPrj.uiSettings.cmdPrebuild,
112 this.curPrj.uiSettings.subpath,
114 this.curPrj.uiSettings.envVars.join(' '));
118 if (!this.isSetupValid()) {
119 return this.alertSvr.warning('Please select first a valid project.', true);
122 this.curPrj.uiSettings.cmdBuild,
123 this.curPrj.uiSettings.subpath,
125 this.curPrj.uiSettings.envVars.join(' '),
130 if (!this.isSetupValid()) {
131 return this.alertSvr.warning('Please select first a valid project.', true);
134 this.curPrj.uiSettings.cmdPopulate,
135 this.curPrj.uiSettings.subpath,
137 this.curPrj.uiSettings.envVars.join(' '),
142 if (!this.isSetupValid()) {
143 return this.alertSvr.warning('Please select first a valid project.', true);
146 this.curPrj.uiSettings.cmdArgs.join(' '),
147 this.curPrj.uiSettings.subpath,
149 this.curPrj.uiSettings.envVars.join(' '),
153 private _exec(cmd: string, dir: string, args: string[], env: string) {
154 if (!this.isSetupValid()) {
155 return this.alertSvr.warning('No active project', true);
157 const prjID = this.curPrj.id;
159 this.cmdOutput += this._outputHeader();
161 const sdkid = this.sdkSvr.getCurrentId();
163 // Detect key=value in env string to build array of string
165 env.split(';').forEach(v => envArr.push(v.trim()));
167 const t0 = performance.now();
168 this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0;
170 this.xdsSvr.exec(prjID, dir, cmd, sdkid, args, envArr)
172 this.startTime.set(String(res.cmdID), t0);
175 this.cmdInfo = 'Last command duration: ' + this._computeTime(t0);
176 this.alertSvr.error('ERROR: ' + err);
180 private _scrollToBottom(): void {
182 this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
186 private _computeTime(t0: number, t1?: number): string {
187 const enlap = Math.round((t1 || performance.now()) - t0);
188 if (enlap < 1000.0) {
189 return enlap.toFixed(2) + ' ms';
191 return (enlap / 1000.0).toFixed(3) + ' seconds';
195 private _outputHeader(): string {
196 return '--- ' + new Date().toString() + ' ---\n';
199 private _outputFooter(): string {