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 { CookieService } from 'ngx-cookie';
6 import 'rxjs/add/operator/scan';
7 import 'rxjs/add/operator/startWith';
9 import { XDSAgentService, ICmdOutput } from '../../@core-xds/services/xdsagent.service';
10 import { ProjectService, IProject } from '../../@core-xds/services/project.service';
11 import { AlertService, IAlert } from '../../@core-xds/services/alert.service';
12 import { SdkService } from '../../@core-xds/services/sdk.service';
15 selector: 'xds-panel-build',
16 templateUrl: './build.component.html',
17 styleUrls: ['./build.component.scss'],
18 encapsulation: ViewEncapsulation.None,
21 export class BuildComponent implements OnInit, AfterViewChecked {
22 @ViewChild('scrollOutput') private scrollContainer: ElementRef;
24 // FIXME workaround of https://github.com/angular/angular-cli/issues/2034
25 // should be removed with angular 5
26 // @Input() curProject: IProject;
27 @Input() curProject = <IProject>null;
29 public buildForm: FormGroup;
30 public subpathCtrl = new FormControl('', Validators.required);
31 public debugEnable = false;
32 public buildIsCollapsed = false;
33 public cmdOutput: string;
34 public cmdInfo: string;
36 private startTime: Map<string, number> = new Map<string, number>();
39 private prjSvr: ProjectService,
40 private xdsSvr: XDSAgentService,
41 private fb: FormBuilder,
42 private alertSvr: AlertService,
43 private sdkSvr: SdkService,
44 private cookie: CookieService,
47 this.cmdInfo = ''; // TODO: to be remove (only for debug)
48 this.buildForm = fb.group({
49 subpath: this.subpathCtrl,
50 cmdClean: ['', Validators.nullValidator],
51 cmdPrebuild: ['', Validators.nullValidator],
52 cmdBuild: ['', Validators.nullValidator],
53 cmdPopulate: ['', Validators.nullValidator],
54 cmdArgs: ['', Validators.nullValidator],
55 envVars: ['', Validators.nullValidator],
60 // Set default settings
61 // TODO save & restore values from cookies
62 this.buildForm.patchValue({
64 cmdClean: 'rm -rf build',
65 cmdPrebuild: 'mkdir -p build && cd build && cmake ..',
66 cmdBuild: 'cd build && make',
67 cmdPopulate: 'cd build && make remote-target-populate',
72 // Command output data tunneling
73 this.xdsSvr.CmdOutput$.subscribe(data => {
74 this.cmdOutput += data.stdout;
75 this.cmdOutput += data.stderr;
79 this.xdsSvr.CmdExit$.subscribe(exit => {
80 if (this.startTime.has(exit.cmdID)) {
81 this.cmdInfo = 'Last command duration: ' + this._computeTime(this.startTime.get(exit.cmdID));
82 this.startTime.delete(exit.cmdID);
85 if (exit && exit.code !== 0) {
86 this.cmdOutput += '--- Command exited with code ' + exit.code + ' ---\n\n';
90 this._scrollToBottom();
93 this.debugEnable = (this.cookie.get('debug_build') === '1');
96 ngAfterViewChecked() {
97 this._scrollToBottom();
106 this.buildForm.value.cmdClean,
107 this.buildForm.value.subpath,
109 this.buildForm.value.envVars);
114 this.buildForm.value.cmdPrebuild,
115 this.buildForm.value.subpath,
117 this.buildForm.value.envVars);
122 this.buildForm.value.cmdBuild,
123 this.buildForm.value.subpath,
125 this.buildForm.value.envVars
131 this.buildForm.value.cmdPopulate,
132 this.buildForm.value.subpath,
134 this.buildForm.value.envVars
140 this.buildForm.value.cmdArgs,
141 this.buildForm.value.subpath,
143 this.buildForm.value.envVars
147 private _exec(cmd: string, dir: string, args: string[], env: string) {
148 if (!this.curProject) {
149 this.alertSvr.warning('No active project', true);
152 // const prjID = this.curProject.id;
153 const prjID = this.prjSvr.getCurrent().id;
155 this.cmdOutput += this._outputHeader();
157 const sdkid = this.sdkSvr.getCurrentId();
159 // Detect key=value in env string to build array of string
161 env.split(';').forEach(v => envArr.push(v.trim()));
163 const t0 = performance.now();
164 this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0;
166 this.xdsSvr.exec(prjID, dir, cmd, sdkid, args, envArr)
168 this.startTime.set(String(res.cmdID), t0);
171 this.cmdInfo = 'Last command duration: ' + this._computeTime(t0);
172 this.alertSvr.error('ERROR: ' + err);
176 private _scrollToBottom(): void {
178 this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight;
182 private _computeTime(t0: number, t1?: number): string {
183 const enlap = Math.round((t1 || performance.now()) - t0);
184 if (enlap < 1000.0) {
185 return enlap.toFixed(2) + ' ms';
187 return (enlap / 1000.0).toFixed(3) + ' seconds';
191 private _outputHeader(): string {
192 return '--- ' + new Date().toString() + ' ---\n';
195 private _outputFooter(): string {