Skip to content

Commit

Permalink
feat(docs): add versioning implementation (#2350)
Browse files Browse the repository at this point in the history
* feat(docs): add versioning implementation

* refactor(docs): remove rimraf, simplify package.json commands

* feat(docs): add docs.archive to gh-pages script

* refactor(docs): remove else, reduce nesting

* feat(docs): docs versioning works with demo.serve

* refactor(docs): deploy and serve from gh-pages, add version check

* refactor(docs): clone/pull via js

* chore(build): simplifed archieve script

* chore(build): more tests
  • Loading branch information
IlyaSurmay authored and valorkin committed Aug 21, 2017
1 parent 6589ee9 commit 91cee71
Show file tree
Hide file tree
Showing 15 changed files with 214 additions and 34 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ npm-debug.log
/demo/dist
/demo/temp
/logs
/gh-pages

#System Files
.DS_Store
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ You will need bootstrap styles (Bootstrap 3)
Or Bootstrap 4
```
<!--- index.html -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
```
To enable bootstrap 4 theme templates in ngx-bootstrap, please read
[here](https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/bootstrap4.md)
Expand Down
24 changes: 14 additions & 10 deletions demo/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule} from '@angular/forms';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule } from '@angular/router';
import { Ng2PageScrollModule } from 'ng2-page-scroll/ng2-page-scroll';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { ngdoc } from '../ng-api-doc';
import { NgApiDoc } from './api-docs/api-docs.model';

import { NgApiDocModule } from './api-docs/index';
import { AppComponent } from './app.component';
import { routes } from './app.routing';
import { GettingStartedComponent } from './getting-started/getting-started.component';
import { AppFooterComponent } from './common/app-footer/app-footer.component';
import { MainMenuComponent } from './common/main-menu/main-menu.component';
import { TopMenuComponent } from './common/top-menu/top-menu.component';
import { SearchFilterPipe } from './common/main-menu/search-filter.pipe';
import { AppFooterComponent } from './common/app-footer/app-footer.component';

import { NgApiDocModule } from './api-docs/index';
import { NgApiDoc } from './api-docs/api-docs.model';
import { ngdoc } from '../ng-api-doc';
import { TopMenuComponent } from './common/top-menu/top-menu.component';
import { GettingStartedComponent } from './getting-started/getting-started.component';

@NgModule({
declarations: [
Expand All @@ -28,8 +30,10 @@ import { ngdoc } from '../ng-api-doc';
NgApiDocModule,
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(routes, {useHash: true}),
Ng2PageScrollModule.forRoot()
Ng2PageScrollModule.forRoot(),
BsDropdownModule.forRoot()
],
providers: [
{provide: NgApiDoc, useValue: ngdoc}
Expand Down
12 changes: 11 additions & 1 deletion demo/src/app/common/top-menu/top-menu.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<div id="top-menu">
<div class="title">
<h2 [routerLink]="['']">ngx-bootstrap</h2>
<h2 [routerLink]="['']">ngx-bootstrap {{currentVersion ? 'v' + currentVersion : ''}}</h2>
</div>
<div class="prev-docs hidden-xs hidden-xs-down" dropdown *ngIf="previousDocs.length" container="body">
<div dropdownToggle class="dropdown-toggle">
Previous docs <span class="caret"></span>
</div>
<ul *dropdownMenu class="dropdown-menu" role="menu">
<li role="menuitem" *ngFor="let item of previousDocs">
<a class="dropdown-item" [href]="appUrl + (isLocalhost ? item.unprefixedUrl : item.url) + (appHash ? '/' + appHash : '')">{{item.version}}</a>
</li>
</ul>
</div>

<div id="mobile-main-menu" (click)="toggle()">
Expand Down
46 changes: 34 additions & 12 deletions demo/src/app/common/top-menu/top-menu.component.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,57 @@
import { AfterViewInit, Component, Inject, Renderer } from '@angular/core';
import { Http } from '@angular/http';
import { DOCUMENT } from '@angular/platform-browser';
import { NavigationEnd, Router } from '@angular/router';
import { NavigationEnd, Router, UrlSerializer } from '@angular/router';
import 'rxjs/add/operator/map';

@Component({
selector: 'top-menu',
templateUrl: './top-menu.component.html'
})
export class TopMenuComponent implements AfterViewInit {
public isShown: boolean = false;
public isShown = false;
public appUrl: string;
public appHash: string;
public currentVersion: string;
public previousDocs: string[] = [];
public isLocalhost = false;

private renderer: Renderer;
private document: any;
private router: Router;

public constructor(renderer: Renderer, @Inject(DOCUMENT) document: any, router: Router) {
this.router = router;
this.renderer = renderer;
this.document = document;
public constructor(private renderer: Renderer,
@Inject(DOCUMENT) private document: any,
private router: Router,
private http: Http) {
}

public ngAfterViewInit(): any {
// todo: remove this sh**
const getUrl = (router: Router) => router.routerState.snapshot.url.slice(0, router.routerState.snapshot.url.indexOf('#'));
this.isLocalhost = location.hostname === 'localhost';
const getUrl = (router: Router) => {
const indexOfHash = router.routerState.snapshot.url.indexOf('#');

return router.routerState.snapshot.url.slice(0, indexOfHash);
};
let _prev = getUrl(this.router);
this.router.events.subscribe((event: any) => {
let _cur = getUrl(this.router);
const _cur = getUrl(this.router);
this.appHash = location.hash === '#/' ? '' : location.hash;
if (event instanceof NavigationEnd && _cur !== _prev) {
_prev = _cur;
this.toggle(false);
}
});

this.http.get('assets/json/versions.json')
.map(res => res.json())
.subscribe((data: any) => {
this.previousDocs = data;
});
this.http.get('assets/json/current-version.json')
.map(res => res.json())
.subscribe((data: any) => {
this.currentVersion = data.version;
});

this.appUrl = location.protocol + '//' + location.hostname + (this.isLocalhost ? ':' + location.port + '/' : '/');
}

public toggle(isShown?: boolean): void {
Expand Down
2 changes: 1 addition & 1 deletion demo/src/app/getting-started/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ You will need bootstrap styles (Bootstrap 3)
Or Bootstrap 4
```
<!--- index.html -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
```
To enable bootstrap 4 theme templates in ngx-bootstrap, please read
[here](https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/bootstrap4.md)
Expand Down
11 changes: 11 additions & 0 deletions demo/src/assets/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ a:hover {
float: left;
}

#top-menu .prev-docs {
position: relative;
}
#top-menu .prev-docs .dropdown-toggle {
color: #fff;
font-size: 18px;
padding-top: 22px;
cursor: pointer;
}


#top-menu .title {
border-right: 1px solid #191924;
min-width: 270px;
Expand Down
1 change: 1 addition & 0 deletions demo/src/assets/json/current-version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":"1.8.1"}
1 change: 1 addition & 0 deletions demo/src/assets/json/versions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"version":"Current","url":"ngx-bootstrap","unprefixedUrl":""},{"version":"1.8.5","url":"ngx-bootstrap/old/1.8.5","unprefixedUrl":"old/1.8.5"}]
2 changes: 1 addition & 1 deletion demo/src/index-bs4.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<link href="https://fonts.googleapis.com/css?family=Roboto:400,300,700" rel="stylesheet" type="text/css">

<!--link to bootstrap.css v4.0.0-alpha-->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
<!--<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">-->
<link rel="stylesheet" href="assets/css/glyphicons.css">
<link rel="stylesheet" href="assets/css/style.css">
Expand Down
2 changes: 1 addition & 1 deletion demo/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<!--link to bootstrap.css-->
<!--<script>window.__theme = 'bs4';</script>-->
<!--<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">-->
<!--<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">-->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/prettify-angulario.css">
Expand Down
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
"description": "Native Angular Bootstrap Components",
"private": true,
"scripts": {
"lite-server": "lite-server -c demo/bs-config.js",
"lite-server": "lite-server -c scripts/bs-config.js",
"typedoc": "typedoc --exclude '**/*.spec.ts' ./src/",
"demo.docs": "node scripts/docs/get-doc.js",
"demo.serve": "run-s build link demo.docs demo.build lite-server",
"demo.gh-pages": "run-s build demo.docs demo.build demo.deploy",
"demo.serve": "run-s build link demo.docs demo.build docs.archive lite-server",
"demo.serve-fast": "run-s build link demo.docs demo.build-fast docs.archive lite-server",
"demo.gh-pages": "run-s build demo.docs demo.build docs.archive demo.deploy",
"demo.build": "ng build -prod --aot --build-optimizer && npm run generate-bs4",
"demo.deploy": "gh-pages -d demo/dist",
"demo-beta-deploy": "gh-pages -d demo/dist -r git@github.com:valorkin/ngx-bootstrap.git -b gh-pages",
"demo.build-fast": "ng build && npm run generate-bs4",
"demo.deploy": "gh-pages -d gh-pages",
"demo-beta-deploy": "gh-pages -d gh-pages -r git@github.com:valorkin/ngx-bootstrap.git -b gh-pages",
"docs.archive": "npm run docs.fetch && node scripts/archive.js",
"docs.fetch": "node scripts/fetch-docs.js",
"link": "ngm link -p src --here",
"lint": "exit 0",
"disable-lint": "tslint \"**/*.ts\" -c tslint.json --fix --type-check -t prose -e \"node_modules/**\" -e \"dist/**\" -e \"temp/**\" -e \"scripts/docs/**\"",
Expand Down Expand Up @@ -88,7 +92,6 @@
"core-js": "^2.4.1",
"cpy": "5.1.0",
"cpy-cli": "1.0.1",
"del-cli": "1.1.0",
"gh-pages": "1.0.0",
"gitignore-to-glob": "0.3.0",
"google-code-prettify": "1.0.5",
Expand Down
110 changes: 110 additions & 0 deletions scripts/archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
const fs = require('fs-extra');
const path = require('path');

const ghPagesDir = 'gh-pages/';
const oldVersionDir = 'gh-pages/old/';
const versionsFilePath = 'assets/json/versions.json';
const currentVersionFilePath = 'assets/json/current-version.json';

const demoSrcDir = 'demo/src';
const demoDistDir = 'demo/dist';
const hostname = 'ngx-bootstrap';

let prevVersion;
const newVersion = require('../package.json').version;

if (!fs.existsSync(ghPagesDir)) {
throw new Error('gh-pages dir wasn\'t found. Run `npm run docs.fetch`');
}

if (!fs.existsSync(demoDistDir)) {
throw new Error('demo/dist dir wasn\'t found. Run `npm run demo.build`');
}

try {
prevVersion = require(path.join('../', ghPagesDir, currentVersionFilePath)).version;
} catch (e) {
prevVersion = require(path.join('../', demoSrcDir, currentVersionFilePath)).version;
}

console.log('Previous version:', prevVersion);
console.log('New version:', newVersion);
const isVersionChanged = prevVersion !== newVersion;


fs.readdir('gh-pages')
// filter files to operate on
.then(filterFileToMove)
// for local development, if version not changed, clean gh-pages folder
.then(files => {
if (isVersionChanged) {
return files;
}
console.log('Version hasn\'t changed. Current gh-pages version will be replaced with the one from demo/dist');
return Promise.all(files.map(file => fs.remove(path.join(ghPagesDir, file))))
.then(() => files)
})
// move old files to corresponding folder, skip for local dev
.then(files => {
if (!isVersionChanged) {
return files;
}

fs.ensureDirSync(path.join(oldVersionDir, prevVersion));

return Promise.all(files
.map(file => ({
from: path.join(ghPagesDir, file),
to: path.join(oldVersionDir, prevVersion, file)
}))
.map((move) => fs.rename(move.from, move.to)));
})
// copy demo dist to gh-pages folder
.then(() => fs.copy(demoDistDir, ghPagesDir))
// generate new version json files
.then(() => {
if (isVersionChanged) {
return generateJson();
}
})
.catch(console.error.bind(console));

function filterFileToMove(files) {
return files.filter((file) => file !== 'old' && file !== '.git');
}

function generateJson() {
return fs.readdir(oldVersionDir)
.then(files => {
let savedVersions = files.map(file => ({
version: file,
url: hostname + '/old/' + file,
unprefixedUrl: 'old/' + file
}));

savedVersions.unshift({version: 'Current', url: hostname, unprefixedUrl: ''});

return savedVersions;
})
.then(versions => {
const content = JSON.stringify(versions);

return Promise
.all(versions.map((ver) => {
if (ver.version === 'Current') {
return Promise.resolve();
}

const _path = path.join(oldVersionDir, ver.version, versionsFilePath);
fs.ensureFileSync(_path);
return writeFile(_path, content);
}))
.then(() => writeFile(path.join(ghPagesDir, versionsFilePath), content))
.then(() => writeFile(path.join(ghPagesDir, currentVersionFilePath), JSON.stringify({version: newVersion})))
.then(() => writeFile(path.join(demoSrcDir, currentVersionFilePath), JSON.stringify({version: newVersion})));
});
}

function writeFile(path, content) {
return fs.writeFile(path, content, 'utf8');
}
2 changes: 1 addition & 1 deletion demo/bs-config.js → scripts/bs-config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
"port": 4200,
"server": {
"baseDir": "./demo/dist",
"baseDir": "./gh-pages",
middleware : { 1 : require('compression')()}
}
};
17 changes: 17 additions & 0 deletions scripts/fetch-docs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require('fs-extra');
const exec = require('child_process').exec;

if (!fs.existsSync('gh-pages')) {
console.log('Cloning the latest version of gh-pages');
runCmd("git clone -b gh-pages --single-branch --depth 1 git@github.com:valor-software/ngx-bootstrap.git gh-pages");
return;
}
console.log('Pulling the latest version of gh-pages');
runCmd("cd gh-pages && git pull && cd ../");

function runCmd(cmd) {
exec(cmd, function (err) {
if (err) console.log('exec err: ' + err);
console.log('Done');
});
}

0 comments on commit 91cee71

Please sign in to comment.