summaryrefslogtreecommitdiffstats
path: root/webapp/src/app/devel/build
diff options
context:
space:
mode:
Diffstat (limited to 'webapp/src/app/devel/build')
-rw-r--r--webapp/src/app/devel/build/build.component.css45
-rw-r--r--webapp/src/app/devel/build/build.component.html74
-rw-r--r--webapp/src/app/devel/build/build.component.ts198
3 files changed, 317 insertions, 0 deletions
diff --git a/webapp/src/app/devel/build/build.component.css b/webapp/src/app/devel/build/build.component.css
new file mode 100644
index 0000000..6784a9f
--- /dev/null
+++ b/webapp/src/app/devel/build/build.component.css
@@ -0,0 +1,45 @@
+.vcenter {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.blocks .btn-primary {
+ margin-left: 5px;
+ margin-right: 5px;
+ margin-top: 5px;
+ border-radius: 4px !important;
+}
+
+.table-center {
+ width: 80%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.table-borderless>tbody>tr>td,
+.table-borderless>tbody>tr>th,
+.table-borderless>tfoot>tr>td,
+.table-borderless>tfoot>tr>th,
+.table-borderless>thead>tr>td,
+.table-borderless>thead>tr>th {
+ border: none;
+}
+
+.btn-large {
+ width: 10em;
+}
+
+.fa-size-x2 {
+ font-size: 18px;
+}
+
+.textarea-scroll {
+ width: 100%;
+ overflow-y: scroll;
+}
+
+h2 {
+ font-family: sans-serif;
+ font-variant: small-caps;
+ font-size: x-large;
+} \ No newline at end of file
diff --git a/webapp/src/app/devel/build/build.component.html b/webapp/src/app/devel/build/build.component.html
new file mode 100644
index 0000000..f4be204
--- /dev/null
+++ b/webapp/src/app/devel/build/build.component.html
@@ -0,0 +1,74 @@
+<div class="panel panel-default">
+ <div class="panel-heading">
+ <h2 class="panel-title">Build</h2>
+ </div>
+ <div class="panel-body">
+ <form [formGroup]="buildForm">
+ <div class="col-xs-12">
+ <table class="table table-borderless table-center">
+ <tbody>
+ <tr>
+ <th>Cross SDK</th>
+ <td>
+ <!-- FIXME why not working ?
+ <sdk-select-dropdown [sdks]="(sdks$ | async)"></sdk-select-dropdown>
+ -->
+ <sdk-select-dropdown></sdk-select-dropdown>
+ </td>
+ </tr>
+ <tr>
+ <th>Project root path</th>
+ <td> <input type="text" disabled style="width:99%;" [value]="curProject && curProject.path"></td>
+ </tr>
+ <tr>
+ <th>Sub-path</th>
+ <td> <input type="text" style="width:99%;" formControlName="subpath"> </td>
+ </tr>
+ <tr>
+ <th>Command arguments</th>
+ <td> <input type="text" style="width:99%;" formControlName="cmdArgs"> </td>
+ </tr>
+ <tr>
+ <th>Env variables</th>
+ <td> <input type="text" style="width:99%;" formControlName="envVars"> </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div class="row">
+ <div class="col-xs-12 text-center">
+ <div class="btn-group blocks">
+ <button class="btn btn-primary btn-large" (click)="preBuild()" [disabled]="!curProject">Pre-Build</button>
+ <button class="btn btn-primary btn-large" (click)="build()" [disabled]="!curProject">Build</button>
+ <button class="btn btn-primary btn-large" (click)="populate()" [disabled]="!curProject ">Populate</button>
+ <button *ngIf="debugEnable" class="btn btn-primary btn-large" (click)="execCmd()" [disabled]="!curProject ">Execute command</button>
+ <button *ngIf="debugEnable" class="btn btn-primary btn-large" (click)="make()" [disabled]="!curProject ">Make</button>
+ </div>
+ </div>
+ </div>
+ </form>
+
+ <div style="margin-left: 2em; margin-right: 2em; ">
+ <div class="row ">
+ <div class="col-xs-10">
+ <div class="row ">
+ <div class="col-xs-4">
+ <label>Command Output</label>
+ </div>
+ <div class="col-xs-8" style="font-size:x-small; margin-top:5px;">
+ {{ cmdInfo }}
+ </div>
+ </div>
+ </div>
+ <div class="col-xs-2">
+ <button class="btn btn-link pull-right " (click)="reset() "><span class="fa fa-eraser fa-size-x2"></span></button>
+ </div>
+ </div>
+ <div class="row ">
+ <div class="col-xs-12 text-center ">
+ <textarea rows="20" class="textarea-scroll" #scrollOutput>{{ cmdOutput }}</textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
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..b7003b1
--- /dev/null
+++ b/webapp/src/app/devel/build/build.component.ts
@@ -0,0 +1,198 @@
+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 { XDSServerService, ICmdOutput } from "../../services/xdsserver.service";
+import { ConfigService, IConfig, IProject } from "../../services/config.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;
+
+ buildForm: FormGroup;
+ subpathCtrl = new FormControl("", Validators.required);
+ debugEnable: boolean = false;
+
+ public cmdOutput: string;
+ public cmdInfo: string;
+
+ private startTime: Map<string, number> = new Map<string, number>();
+
+ constructor(private configSvr: ConfigService,
+ private xdsSvr: XDSServerService,
+ 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,
+ cmdArgs: ["", Validators.nullValidator],
+ envVars: ["", Validators.nullValidator],
+ });
+ }
+
+ ngOnInit() {
+ // Command output data tunneling
+ this.xdsSvr.CmdOutput$.subscribe(data => {
+ this.cmdOutput += data.stdout + "\n";
+ });
+
+ // 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") !== "");
+ }
+
+ ngAfterViewChecked() {
+ this._scrollToBottom();
+ }
+
+ reset() {
+ this.cmdOutput = '';
+ }
+
+ preBuild() {
+ this._exec(
+ "mkdir -p build && cd build && cmake ..",
+ this.buildForm.value.subpath,
+ [],
+ this.buildForm.value.envVars);
+ }
+
+ build() {
+ this._exec(
+ "cd build && make",
+ this.buildForm.value.subpath,
+ this.buildForm.value.cmdArgs,
+ this.buildForm.value.envVars
+ );
+ }
+
+ populate() {
+ this._exec(
+ "SEB_TODO_script_populate",
+ 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";
+ }
+} \ No newline at end of file