mirror of
https://github.com/inspec/inspec
synced 2024-11-23 13:13:22 +00:00
integrate xterm for shell emulation
This commit is contained in:
parent
1ea965080a
commit
679ae64be2
18 changed files with 275 additions and 161 deletions
|
@ -1,22 +0,0 @@
|
|||
0 info it worked if it ends with ok
|
||||
1 verbose cli [ '/Users/vjeffrey/.nvm/versions/node/v5.6.0/bin/node',
|
||||
1 verbose cli '/Users/vjeffrey/.nvm/versions/node/v5.6.0/bin/npm',
|
||||
1 verbose cli 'start' ]
|
||||
2 info using npm@3.6.0
|
||||
3 info using node@v5.6.0
|
||||
4 verbose stack Error: ENOENT: no such file or directory, open '/Users/vjeffrey/code/compliance/inspec/www/package.json'
|
||||
4 verbose stack at Error (native)
|
||||
5 verbose cwd /Users/vjeffrey/code/compliance/inspec/www
|
||||
6 error Darwin 15.6.0
|
||||
7 error argv "/Users/vjeffrey/.nvm/versions/node/v5.6.0/bin/node" "/Users/vjeffrey/.nvm/versions/node/v5.6.0/bin/npm" "start"
|
||||
8 error node v5.6.0
|
||||
9 error npm v3.6.0
|
||||
10 error path /Users/vjeffrey/code/compliance/inspec/www/package.json
|
||||
11 error code ENOENT
|
||||
12 error errno -2
|
||||
13 error syscall open
|
||||
14 error enoent ENOENT: no such file or directory, open '/Users/vjeffrey/code/compliance/inspec/www/package.json'
|
||||
15 error enoent ENOENT: no such file or directory, open '/Users/vjeffrey/code/compliance/inspec/www/package.json'
|
||||
15 error enoent This is most likely not a problem with npm itself
|
||||
15 error enoent and is related to npm not being able to find a file.
|
||||
16 verbose exit [ -2, true ]
|
2
www/tutorial/.gitignore
vendored
2
www/tutorial/.gitignore
vendored
|
@ -8,4 +8,4 @@
|
|||
npm-debug.log
|
||||
|
||||
*.js
|
||||
*.map.js
|
||||
*.js.map
|
|
@ -1,28 +1,41 @@
|
|||
|
||||
h1 {
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: 250%;
|
||||
}
|
||||
|
||||
.demo-view {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.instructions {
|
||||
.terminal-nav {
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
top: 30%;
|
||||
left: 35%;
|
||||
width: 70%;
|
||||
height: 35%;
|
||||
margin-top: -9em;
|
||||
margin-left: -15em;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
line-height: 30px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 120px;
|
||||
height: 60px;
|
||||
color: #888;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
font-size: 30px;
|
||||
font-family: "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-weight: 300;
|
||||
transition: all 200ms ease-in;
|
||||
cursor: pointer;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.instructions-content {
|
||||
margin: 20px 20px 20px 20px;
|
||||
.terminal-nav span:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.guide {
|
||||
font-family: monospace;
|
||||
font-size: 1.2rem;
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.cli {
|
||||
font-family: monospace;
|
||||
font-size: 1.2rem;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,28 @@
|
|||
<h1>InSpec Demo</h1>
|
||||
<div class="demo-view">
|
||||
<div class="instructions">
|
||||
<div class="instructions-content">
|
||||
<pre> {{instructions}} </pre>
|
||||
</div>
|
||||
</div>
|
||||
<terminal-view [responsesArray]="responsesArray" (stepCounter)="stepCounter=$event"></terminal-view>
|
||||
</div>
|
||||
<div class="terminal-nav">
|
||||
<!--TODO: make these functional-->
|
||||
<span> < </span>
|
||||
<span> > </span>
|
||||
<span> x </span>
|
||||
</div>
|
||||
|
||||
<div class="guide" *ngIf="counter === 0">
|
||||
Welcome to the interactive InSpec demo!
|
||||
<p>
|
||||
This tutorial is great for getting familiar with InSpec. There are 3 sections:
|
||||
</p>
|
||||
<ol>
|
||||
<!--TODO: give these real links-->
|
||||
<li><a href="...">InSpec commandline interface</a></li>
|
||||
<li><a href="...">InSpec interactive shell</a></li>
|
||||
<li><a href="...">Create test and compliance profile</a></li>
|
||||
</ol>
|
||||
<p>Use the command "next" to move forward or "prev" to move backwards.</p>
|
||||
</div>
|
||||
|
||||
<div class="guide" *ngIf="counter > 0">
|
||||
<pre > {{ instructions }} </pre>
|
||||
</div>
|
||||
|
||||
<div class="cli">
|
||||
<xterm-terminal (stepNumber)="updateInstructions(stepNumber=$event)" [responsesArray]="responsesArray"></xterm-terminal>
|
||||
</div>
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"app.component.js","sourceRoot":"","sources":["app.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAuD,eAAe,CAAC,CAAA;AACvE,qBAA+B,eAAe,CAAC,CAAA;AAC/C,mBAA2B,SAAS,CAAC,CAAA;AACrC,qBAA+B,eAAe,CAAC,CAAA;AAC/C,wCAAsC,yCAAyC,CAAC,CAAA;AAUhF;IAME,sBAAoB,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;QAJ9B,gBAAW,GAAW,CAAC,CAAC;IAIU,CAAC;IAEnC,+BAAQ,GAAR;QACE,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,yCAAkB,GAAlB;QACE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;IAED,sCAAe,GAAf;QAAA,iBAYC;QAXC,eAAU,CAAC,QAAQ,CACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAC/C,CAAC,SAAS,CACT,UAAA,IAAI;YACF,KAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,KAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC,EACD,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC1B,CAAC;IACJ,CAAC;IAED,mCAAY,GAAZ;QAAA,iBAaC;QAZC,eAAU,CAAC,QAAQ,CACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI;QAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,IAAI;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,IAAI;QAC7C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,EAAE,IAAI;QACrD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,IAAI;SAC1D,CAAC,SAAS,CACT,UAAA,IAAI;YACF,KAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC,EACD,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC1B,CAAC;IACJ,CAAC;IApDH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,wBAAwB;YACrC,SAAS,EAAE,CAAC,uBAAuB,CAAC;YACpC,SAAS,EAAE,CAAE,qBAAc,CAAE;YAC7B,UAAU,EAAE,CAAE,+CAAqB,CAAE;SACtC,CAAC;;oBAAA;IA+CF,mBAAC;AAAD,CAAC,AA7CD,IA6CC;AA7CY,oBAAY,eA6CxB,CAAA"}
|
||||
{"version":3,"file":"app.component.js","sourceRoot":"","sources":["app.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAkC,eAAe,CAAC,CAAA;AAClD,qBAA+B,eAAe,CAAC,CAAA;AAC/C,mBAA2B,SAAS,CAAC,CAAA;AACrC,qBAA+B,eAAe,CAAC,CAAA;AAC/C,yCAAuC,2CAA2C,CAAC,CAAA;AAUnF;IAME,sBAAoB,IAAU;QAAV,SAAI,GAAJ,IAAI,CAAM;IAAI,CAAC;IAEnC,+BAAQ,GAAR;QACE,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,yCAAkB,GAAlB,UAAmB,IAAI;QACrB,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACb,IAAI,GAAG,CAAC,CAAA;QACV,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,sCAAe,GAAf;QAAA,iBAYC;QAXC,eAAU,CAAC,QAAQ,CACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,EAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAC/C,CAAC,SAAS,CACT,UAAA,IAAI;YACF,KAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,KAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC,EACD,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC1B,CAAC;IACJ,CAAC;IAED,mCAAY,GAAZ;QAAA,iBAaC;QAZC,eAAU,CAAC,QAAQ,CACf,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI;QAC9C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,IAAI;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,IAAI;QAC7C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,EAAE,IAAI;QACrD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC,IAAI;SAC1D,CAAC,SAAS,CACT,UAAA,IAAI;YACF,KAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC,EACD,UAAA,GAAG,IAAI,OAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAlB,CAAkB,CAC1B,CAAC;IACJ,CAAC;IAxDH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,QAAQ;YAClB,WAAW,EAAE,wBAAwB;YACrC,SAAS,EAAE,CAAC,uBAAuB,CAAC;YACpC,SAAS,EAAE,CAAE,qBAAc,CAAE;YAC7B,UAAU,EAAE,CAAE,iDAAsB,CAAE;SACvC,CAAC;;oBAAA;IAmDF,mBAAC;AAAD,CAAC,AAjDD,IAiDC;AAjDY,oBAAY,eAiDxB,CAAA"}
|
|
@ -1,22 +1,22 @@
|
|||
import { Component, OnInit, Input, SimpleChange } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Http, Response } from '@angular/http';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { HTTP_PROVIDERS } from '@angular/http';
|
||||
import { TerminalViewComponent } from './terminal-view/terminal-view.component';
|
||||
import { XtermTerminalComponent } from './xterm-terminal/xterm-terminal.component';
|
||||
|
||||
@Component({
|
||||
selector: 'my-app',
|
||||
templateUrl: 'app/app.component.html',
|
||||
styleUrls: ['app/app.component.css'],
|
||||
providers: [ HTTP_PROVIDERS ],
|
||||
directives: [ TerminalViewComponent ]
|
||||
directives: [ XtermTerminalComponent ]
|
||||
})
|
||||
|
||||
export class AppComponent implements OnInit {
|
||||
instructions: any;
|
||||
currentStep: number = 0;
|
||||
instructionsArray: any;
|
||||
responsesArray: any;
|
||||
counter: number;
|
||||
|
||||
constructor(private http: Http) { }
|
||||
|
||||
|
@ -25,8 +25,12 @@ export class AppComponent implements OnInit {
|
|||
this.getResponses();
|
||||
}
|
||||
|
||||
updateInstructions() {
|
||||
this.instructions = this.instructionsArray[this.currentStep]['_body'];
|
||||
updateInstructions(step) {
|
||||
if (step < 0) {
|
||||
step = 0
|
||||
}
|
||||
this.counter = step;
|
||||
this.instructions = this.instructionsArray[step]['_body'];
|
||||
}
|
||||
|
||||
getInstructions() {
|
||||
|
@ -37,7 +41,7 @@ export class AppComponent implements OnInit {
|
|||
).subscribe(
|
||||
data => {
|
||||
this.instructionsArray = data;
|
||||
this.updateInstructions();
|
||||
this.updateInstructions(0);
|
||||
},
|
||||
err => console.error(err)
|
||||
);
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
Step 0
|
||||
write words here to tell people what to do.
|
||||
|
||||
stand up! turn around! reach high for the sky!
|
||||
well done!
|
||||
now start by typing
|
||||
'next'
|
||||
<b>Welcome to the interactive InSpec demo!</b>
|
||||
<p>
|
||||
This tutorial is great for getting familiar with InSpec. There are 3 sections:
|
||||
</p>
|
||||
<ol>
|
||||
<!--TODO: give these real links-->
|
||||
<li><a href="...">InSpec commandline interface</a></li>
|
||||
<li><a href="...">InSpec interactive shell</a></li>
|
||||
<li><a href="...">Create test and compliance profile</a></li>
|
||||
</ol>
|
||||
<p><b>Use the command "next" to move forward</b> or "prev" to move backwards.</p>
|
|
@ -1,33 +0,0 @@
|
|||
.terminal-body {
|
||||
display: inline-block;
|
||||
position: fixed;
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
top: 40%;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.left {
|
||||
float: left;
|
||||
padding-right: 4px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
background-color: black;
|
||||
border: none;
|
||||
color: white;
|
||||
height: 50px;
|
||||
width: 98%;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
textarea:focus, input:focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
pre {
|
||||
color: white;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<div class="terminal-body">
|
||||
<div class="left"> $ </div>
|
||||
<input type="text" id="input" #box (keyup.enter)="evalInput(box.value)" autofocus>
|
||||
<pre id="result"> {{response}}</pre>
|
||||
</div>
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"terminal-view.component.js","sourceRoot":"","sources":["terminal-view.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAuD,eAAe,CAAC,CAAA;AAOvE;IAAA;QAEY,gBAAW,GAAyB,IAAI,mBAAY,EAAU,CAAC;QAEzE,SAAI,GAAW,CAAC,CAAC;IAiCnB,CAAC;IA/BC,yCAAS,GAAT,UAAU,KAAK;QACb,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;YACf,oBAAoB;YACpB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,CAAC;YACJ,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,+CAAe,GAAf,UAAgB,KAAK;QACnB,IAAI,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAChD,EAAE,CAAC,CAAC,MAAM,KAAK,kBAAkB,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClD,CAAC;QAAC,IAAI,CAAC,CAAC;YACN,IAAI,CAAC,QAAQ,GAAG,qCAAqC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QAC3E,CAAC;IACH,CAAC;IAnCD;QAAC,YAAK,EAAE;;iEAAA;IACR;QAAC,aAAM,EAAE;;8DAAA;IAPX;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,eAAe;YACzB,WAAW,EAAE,gDAAgD;YAC7D,SAAS,EAAE,CAAE,+CAA+C,CAAE;SAC/D,CAAC;;6BAAA;IAsCF,4BAAC;AAAD,CAAC,AArCD,IAqCC;AArCY,6BAAqB,wBAqCjC,CAAA"}
|
|
@ -1,45 +0,0 @@
|
|||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'terminal-view',
|
||||
templateUrl: 'app/terminal-view/terminal-view.component.html',
|
||||
styleUrls: [ 'app/terminal-view/terminal-view.component.css' ]
|
||||
})
|
||||
export class TerminalViewComponent {
|
||||
@Input() responsesArray: any;
|
||||
@Output() stepCounter: EventEmitter<number> = new EventEmitter<number>();
|
||||
response: any;
|
||||
step: number = 0;
|
||||
|
||||
evalInput(value) {
|
||||
if (value.match(/^next\s*/)) {
|
||||
this.step += 1;
|
||||
// TODO: fix this!!!
|
||||
this.stepCounter.emit(this.step);
|
||||
}
|
||||
else if (value.match(/^ls\s*/)) {
|
||||
this.response = this.responsesArray[1]['_body'];
|
||||
}
|
||||
else if (value.match(/^pwd\s*/)) {
|
||||
this.response = this.responsesArray[2]['_body'];
|
||||
}
|
||||
else if (value.match(/^inspec exec\s*(.*)/)) {
|
||||
this.parseInspecExec(value);
|
||||
}
|
||||
else if (value.match(/^inspec\s*version\s*/)) {
|
||||
this.response = this.responsesArray[4]['_body'];
|
||||
}
|
||||
else {
|
||||
this.response = this.responsesArray[0]['_body'];
|
||||
}
|
||||
}
|
||||
|
||||
parseInspecExec(value) {
|
||||
let target = value.match(/^inspec exec\s*(.*)/);
|
||||
if (target === 'examples/profile') {
|
||||
this.response = this.responsesArray[3]['_body'];
|
||||
} else {
|
||||
this.response = "Could not fetch inspec profile in '" + target[1] + "' ";
|
||||
}
|
||||
}
|
||||
}
|
23
www/tutorial/app/xterm-terminal/xterm-terminal.component.css
Normal file
23
www/tutorial/app/xterm-terminal/xterm-terminal.component.css
Normal file
|
@ -0,0 +1,23 @@
|
|||
#terminal-container {
|
||||
width: 1200px;
|
||||
height: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/*the app was having trouble setting the following css
|
||||
classes, so i added a host and /deep/ call to ensure they get set*/
|
||||
|
||||
:host /deep/ .terminal {
|
||||
background-color: black;
|
||||
color: #fafafa;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
:host /deep/ .terminal:focus .terminal-cursor {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
:host /deep/ .xterm-helpers {
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
<!--try to bring in xterm-->
|
||||
<div (keyup)="onKey($event)" id="terminal-container"></div>
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"xterm-terminal.component.js","sourceRoot":"","sources":["xterm-terminal.component.ts"],"names":[],"mappings":"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"}
|
150
www/tutorial/app/xterm-terminal/xterm-terminal.component.ts
Normal file
150
www/tutorial/app/xterm-terminal/xterm-terminal.component.ts
Normal file
|
@ -0,0 +1,150 @@
|
|||
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
|
||||
declare var Terminal: any;
|
||||
|
||||
@Component({
|
||||
selector: 'xterm-terminal',
|
||||
templateUrl: 'app/xterm-terminal/xterm-terminal.component.html',
|
||||
styleUrls: ['app/xterm-terminal/xterm-terminal.component.css']
|
||||
})
|
||||
export class XtermTerminalComponent implements OnInit {
|
||||
@Input() responsesArray: any;
|
||||
@Output() stepNumber: EventEmitter<number> = new EventEmitter<number>();
|
||||
step: number = 0;
|
||||
shellprompt: string;
|
||||
buffer: string = '';
|
||||
terminalContainer: any;
|
||||
term: any;
|
||||
optionElements: any;
|
||||
cols: any;
|
||||
rows: any;
|
||||
|
||||
ngOnInit() {
|
||||
this.terminalContainer = document.getElementById('terminal-container'),
|
||||
this.optionElements = {
|
||||
cursorBlink: document.querySelector('#option-cursor-blink')
|
||||
},
|
||||
this.cols = '70',
|
||||
this.rows = '70';
|
||||
this.createTerminal();
|
||||
}
|
||||
|
||||
createTerminal() {
|
||||
while (this.terminalContainer.children.length) {
|
||||
this.terminalContainer.removeChild(this.terminalContainer.children[0]);
|
||||
}
|
||||
this.term = new Terminal({
|
||||
cursorBlink: true
|
||||
});
|
||||
|
||||
this.term.open(this.terminalContainer);
|
||||
this.term.fit();
|
||||
|
||||
var initialGeometry = this.term.proposeGeometry(),
|
||||
cols = initialGeometry.cols,
|
||||
rows = initialGeometry.rows;
|
||||
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
this.runFakeTerminal()
|
||||
}
|
||||
|
||||
runFakeTerminal() {
|
||||
if (this.term._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.term._initialized = true;
|
||||
this.setPrompt();
|
||||
|
||||
this.term.writeln('WELCOME TO YOUR INSPEC DEMO SHELL FOOL!');
|
||||
this.term.writeln('');
|
||||
this.setPrompt();
|
||||
}
|
||||
|
||||
setPrompt() {
|
||||
this.buffer = ''
|
||||
this.shellprompt = '$ ';
|
||||
this.term.write('\r\n' + this.shellprompt);
|
||||
}
|
||||
|
||||
setInspecShellPrompt() {
|
||||
this.term.write('\r\ninspec> ');
|
||||
this.setPrompt();
|
||||
}
|
||||
|
||||
onKey(ev) {
|
||||
var shell = null
|
||||
var printable = (!ev.altKey && !ev.altGraphKey && !ev.ctrlKey && !ev.metaKey)
|
||||
|
||||
// on enter, check buffer and print response
|
||||
if (ev.keyCode == 13) {
|
||||
this.term.write('\r\n');
|
||||
|
||||
// play with inspec shell
|
||||
if (this.buffer == 'inspec shell') {
|
||||
shell = 'inspec-shell'
|
||||
this.term.writeln('Welcome to the interactive InSpec Shell');
|
||||
this.term.writeln('To find out how to use it, type: help')
|
||||
this.setInspecShellPrompt();
|
||||
}
|
||||
|
||||
// exit inspec shell
|
||||
if (this.buffer == 'exit' && shell == 'inspec-shell' ) {
|
||||
shell = null
|
||||
this.setPrompt();
|
||||
}
|
||||
|
||||
// TODO: functionality for inspec shell
|
||||
if (shell == 'inspec-shell') {
|
||||
if (this.buffer == 'os.params') {
|
||||
this.term.writeln('print file content for shell');
|
||||
}
|
||||
|
||||
} else {
|
||||
// match on various commands or print inspec help
|
||||
if (this.buffer.match(/^inspec\s*exec\s*.*/)) {
|
||||
this.parseInspecExec(this.buffer);
|
||||
}
|
||||
else if (this.buffer.match(/^inspec\s*version\s*/)) {
|
||||
this.term.writeln(this.responsesArray[4]['_body']);
|
||||
this.setPrompt();
|
||||
}
|
||||
else if (this.buffer.match(/^next\s*/)) {
|
||||
this.step += 1;
|
||||
this.stepNumber.emit(this.step);
|
||||
this.setPrompt();
|
||||
}
|
||||
else if (this.buffer.match(/^previous\s*/)) {
|
||||
this.step -= 1;
|
||||
this.stepNumber.emit(this.step);
|
||||
this.setPrompt();
|
||||
}
|
||||
else {
|
||||
this.term.writeln(this.responsesArray[0]['_body']);
|
||||
this.setPrompt();
|
||||
}
|
||||
}
|
||||
|
||||
// on backspace, pop characters from buffer
|
||||
} else if (ev.keyCode == 8) {
|
||||
if (this.term.x > 2) {
|
||||
this.buffer = this.buffer.substr(0, this.buffer.length-1)
|
||||
this.term.write('\b \b');
|
||||
}
|
||||
} else if (printable) {
|
||||
this.term.write(ev.key);
|
||||
this.buffer += ev.key;
|
||||
}
|
||||
}
|
||||
|
||||
parseInspecExec(value) {
|
||||
let target = value.match(/^inspec exec\s*(.*)/);
|
||||
if (target[1] === 'examples/profile') {
|
||||
this.term.writeln(this.responsesArray[3]['_body']);
|
||||
this.setPrompt();
|
||||
} else {
|
||||
this.term.writeln("Could not fetch inspec profile in '" + target[1] + "' ");
|
||||
this.setPrompt();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,9 @@
|
|||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||
<!-- 2. Configure SystemJS -->
|
||||
<script src="systemjs.config.js"></script>
|
||||
<!-- 3. Load Xterm -->
|
||||
<script src="node_modules/xterm/src/xterm.js"></script>
|
||||
<script src="node_modules/xterm/addons/fit/fit.js"></script>
|
||||
<script>
|
||||
System.import('app').catch(function(err){ console.error(err); });
|
||||
</script>
|
||||
|
|
|
@ -21,18 +21,19 @@
|
|||
"@angular/router": "3.0.0-rc.1",
|
||||
"@angular/router-deprecated": "2.0.0-rc.2",
|
||||
"@angular/upgrade": "2.0.0-rc.5",
|
||||
"systemjs": "0.19.27",
|
||||
"angular2-in-memory-web-api": "0.0.15",
|
||||
"bootstrap": "^3.3.6",
|
||||
"core-js": "^2.4.0",
|
||||
"reflect-metadata": "^0.1.3",
|
||||
"rxjs": "5.0.0-beta.6",
|
||||
"zone.js": "^0.6.12",
|
||||
"angular2-in-memory-web-api": "0.0.15",
|
||||
"bootstrap": "^3.3.6"
|
||||
"systemjs": "0.19.27",
|
||||
"xterm": "git://github.com/sourcelair/xterm.js.git",
|
||||
"zone.js": "^0.6.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^2.0.0",
|
||||
"lite-server": "^2.2.0",
|
||||
"typescript": "^1.8.10",
|
||||
"typings":"^1.0.4"
|
||||
"typings": "^1.0.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* Master Styles */
|
||||
|
||||
body {
|
||||
color: white;
|
||||
background-color: black;
|
||||
margin: 2em;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 100;
|
||||
}
|
Loading…
Reference in a new issue