X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=webapp%2Fsrc%2Fapp%2Fdevel%2Fbuild%2Fbuild.component.ts;fp=webapp%2Fsrc%2Fapp%2Fdevel%2Fbuild%2Fbuild.component.ts;h=87df4e194d673ca0dc792ef5fb4c219c632173d8;hb=97ca1f277dc8b6973d6fa67add5593a9c395ce60;hp=0000000000000000000000000000000000000000;hpb=12a20d0905b0d3e7e0f4c9ec8ee619f683256d71;p=src%2Fxds%2Fxds-agent.git diff --git a/webapp/src/app/devel/build/build.component.ts b/webapp/src/app/devel/build/build.component.ts new file mode 100644 index 0000000..87df4e1 --- /dev/null +++ b/webapp/src/app/devel/build/build.component.ts @@ -0,0 +1,223 @@ +import { Component, AfterViewChecked, ElementRef, ViewChild, OnInit, Input } from '@angular/core'; +import { Observable } from 'rxjs'; +import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms'; +import { CookieService } from 'ngx-cookie'; + +import 'rxjs/add/operator/scan'; +import 'rxjs/add/operator/startWith'; + +import { XDSAgentService, ICmdOutput } from "../../services/xdsagent.service"; +import { ProjectService, IProject } from "../../services/project.service"; +import { AlertService, IAlert } from "../../services/alert.service"; +import { SdkService } from "../../services/sdk.service"; + +@Component({ + selector: 'panel-build', + moduleId: module.id, + templateUrl: './build.component.html', + styleUrls: ['./build.component.css'] +}) + +export class BuildComponent implements OnInit, AfterViewChecked { + @ViewChild('scrollOutput') private scrollContainer: ElementRef; + + @Input() curProject: IProject; + + public buildForm: FormGroup; + public subpathCtrl = new FormControl("", Validators.required); + public debugEnable: boolean = false; + public buildIsCollapsed: boolean = false; + public cmdOutput: string; + public cmdInfo: string; + + private startTime: Map = new Map(); + + constructor( + private xdsSvr: XDSAgentService, + private fb: FormBuilder, + private alertSvr: AlertService, + private sdkSvr: SdkService, + private cookie: CookieService, + ) { + this.cmdOutput = ""; + this.cmdInfo = ""; // TODO: to be remove (only for debug) + this.buildForm = fb.group({ + subpath: this.subpathCtrl, + cmdClean: ["", Validators.nullValidator], + cmdPrebuild: ["", Validators.nullValidator], + cmdBuild: ["", Validators.nullValidator], + cmdPopulate: ["", Validators.nullValidator], + cmdArgs: ["", Validators.nullValidator], + envVars: ["", Validators.nullValidator], + }); + } + + ngOnInit() { + // Set default settings + // TODO save & restore values from cookies + this.buildForm.patchValue({ + subpath: "", + cmdClean: "rm -rf build", + cmdPrebuild: "mkdir -p build && cd build && cmake ..", + cmdBuild: "cd build && make", + cmdPopulate: "cd build && make remote-target-populate", + cmdArgs: "", + envVars: "", + }); + + // Command output data tunneling + this.xdsSvr.CmdOutput$.subscribe(data => { + this.cmdOutput += data.stdout; + this.cmdOutput += data.stderr; + }); + + // Command exit + this.xdsSvr.CmdExit$.subscribe(exit => { + if (this.startTime.has(exit.cmdID)) { + this.cmdInfo = 'Last command duration: ' + this._computeTime(this.startTime.get(exit.cmdID)); + this.startTime.delete(exit.cmdID); + } + + if (exit && exit.code !== 0) { + this.cmdOutput += "--- Command exited with code " + exit.code + " ---\n\n"; + } + }); + + this._scrollToBottom(); + + // only use for debug + this.debugEnable = (this.cookie.get("debug_build") === "1"); + } + + ngAfterViewChecked() { + this._scrollToBottom(); + } + + reset() { + this.cmdOutput = ''; + } + + clean() { + this._exec( + this.buildForm.value.cmdClean, + this.buildForm.value.subpath, + [], + this.buildForm.value.envVars); + } + + preBuild() { + this._exec( + this.buildForm.value.cmdPrebuild, + this.buildForm.value.subpath, + [], + this.buildForm.value.envVars); + } + + build() { + this._exec( + this.buildForm.value.cmdBuild, + this.buildForm.value.subpath, + [], + this.buildForm.value.envVars + ); + } + + populate() { + this._exec( + this.buildForm.value.cmdPopulate, + this.buildForm.value.subpath, + [], // args + this.buildForm.value.envVars + ); + } + + execCmd() { + this._exec( + this.buildForm.value.cmdArgs, + this.buildForm.value.subpath, + [], + this.buildForm.value.envVars + ); + } + + private _exec(cmd: string, dir: string, args: string[], env: string) { + if (!this.curProject) { + this.alertSvr.warning('No active project', true); + } + + let prjID = this.curProject.id; + + this.cmdOutput += this._outputHeader(); + + let sdkid = this.sdkSvr.getCurrentId(); + + // Detect key=value in env string to build array of string + let envArr = []; + env.split(';').forEach(v => envArr.push(v.trim())); + + let t0 = performance.now(); + this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0; + + this.xdsSvr.exec(prjID, dir, cmd, sdkid, args, envArr) + .subscribe(res => { + this.startTime.set(String(res.cmdID), t0); + }, + err => { + this.cmdInfo = 'Last command duration: ' + this._computeTime(t0); + this.alertSvr.error('ERROR: ' + err); + }); + } + + make(args: string) { + if (!this.curProject) { + this.alertSvr.warning('No active project', true); + } + + let prjID = this.curProject.id; + + this.cmdOutput += this._outputHeader(); + + let sdkid = this.sdkSvr.getCurrentId(); + + let argsArr = args ? args.split(' ') : this.buildForm.value.cmdArgs.split(' '); + + // Detect key=value in env string to build array of string + let envArr = []; + this.buildForm.value.envVars.split(';').forEach(v => envArr.push(v.trim())); + + let t0 = performance.now(); + this.cmdInfo = 'Start build of ' + prjID + ' at ' + t0; + + this.xdsSvr.make(prjID, this.buildForm.value.subpath, sdkid, argsArr, envArr) + .subscribe(res => { + this.startTime.set(String(res.cmdID), t0); + }, + err => { + this.cmdInfo = 'Last command duration: ' + this._computeTime(t0); + this.alertSvr.error('ERROR: ' + err); + }); + } + + private _scrollToBottom(): void { + try { + this.scrollContainer.nativeElement.scrollTop = this.scrollContainer.nativeElement.scrollHeight; + } catch (err) { } + } + + private _computeTime(t0: number, t1?: number): string { + let enlap = Math.round((t1 || performance.now()) - t0); + if (enlap < 1000.0) { + return enlap.toFixed(2) + ' ms'; + } else { + return (enlap / 1000.0).toFixed(3) + ' seconds'; + } + } + + private _outputHeader(): string { + return "--- " + new Date().toString() + " ---\n"; + } + + private _outputFooter(): string { + return "\n"; + } +}