Skip to content

Commit 91cee71

Browse files
IlyaSurmayvalorkin
authored andcommitted
feat(docs): add versioning implementation (#2350)
* 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
1 parent 6589ee9 commit 91cee71

File tree

15 files changed

+214
-34
lines changed

15 files changed

+214
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ npm-debug.log
2626
/demo/dist
2727
/demo/temp
2828
/logs
29+
/gh-pages
2930

3031
#System Files
3132
.DS_Store

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ You will need bootstrap styles (Bootstrap 3)
4343
Or Bootstrap 4
4444
```
4545
<!--- index.html -->
46-
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
46+
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
4747
```
4848
To enable bootstrap 4 theme templates in ngx-bootstrap, please read
4949
[here](https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/bootstrap4.md)

demo/src/app/app.module.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
import { BrowserModule } from '@angular/platform-browser';
21
import { NgModule } from '@angular/core';
3-
import { FormsModule} from '@angular/forms';
2+
import { FormsModule } from '@angular/forms';
3+
import { HttpModule } from '@angular/http';
4+
import { BrowserModule } from '@angular/platform-browser';
45
import { RouterModule } from '@angular/router';
56
import { Ng2PageScrollModule } from 'ng2-page-scroll/ng2-page-scroll';
7+
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
8+
import { ngdoc } from '../ng-api-doc';
9+
import { NgApiDoc } from './api-docs/api-docs.model';
10+
11+
import { NgApiDocModule } from './api-docs/index';
612
import { AppComponent } from './app.component';
713
import { routes } from './app.routing';
8-
import { GettingStartedComponent } from './getting-started/getting-started.component';
14+
import { AppFooterComponent } from './common/app-footer/app-footer.component';
915
import { MainMenuComponent } from './common/main-menu/main-menu.component';
10-
import { TopMenuComponent } from './common/top-menu/top-menu.component';
1116
import { SearchFilterPipe } from './common/main-menu/search-filter.pipe';
12-
import { AppFooterComponent } from './common/app-footer/app-footer.component';
13-
14-
import { NgApiDocModule } from './api-docs/index';
15-
import { NgApiDoc } from './api-docs/api-docs.model';
16-
import { ngdoc } from '../ng-api-doc';
17+
import { TopMenuComponent } from './common/top-menu/top-menu.component';
18+
import { GettingStartedComponent } from './getting-started/getting-started.component';
1719

1820
@NgModule({
1921
declarations: [
@@ -28,8 +30,10 @@ import { ngdoc } from '../ng-api-doc';
2830
NgApiDocModule,
2931
BrowserModule,
3032
FormsModule,
33+
HttpModule,
3134
RouterModule.forRoot(routes, {useHash: true}),
32-
Ng2PageScrollModule.forRoot()
35+
Ng2PageScrollModule.forRoot(),
36+
BsDropdownModule.forRoot()
3337
],
3438
providers: [
3539
{provide: NgApiDoc, useValue: ngdoc}

demo/src/app/common/top-menu/top-menu.component.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
<div id="top-menu">
22
<div class="title">
3-
<h2 [routerLink]="['']">ngx-bootstrap</h2>
3+
<h2 [routerLink]="['']">ngx-bootstrap {{currentVersion ? 'v' + currentVersion : ''}}</h2>
4+
</div>
5+
<div class="prev-docs hidden-xs hidden-xs-down" dropdown *ngIf="previousDocs.length" container="body">
6+
<div dropdownToggle class="dropdown-toggle">
7+
Previous docs <span class="caret"></span>
8+
</div>
9+
<ul *dropdownMenu class="dropdown-menu" role="menu">
10+
<li role="menuitem" *ngFor="let item of previousDocs">
11+
<a class="dropdown-item" [href]="appUrl + (isLocalhost ? item.unprefixedUrl : item.url) + (appHash ? '/' + appHash : '')">{{item.version}}</a>
12+
</li>
13+
</ul>
414
</div>
515

616
<div id="mobile-main-menu" (click)="toggle()">

demo/src/app/common/top-menu/top-menu.component.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,57 @@
11
import { AfterViewInit, Component, Inject, Renderer } from '@angular/core';
2+
import { Http } from '@angular/http';
23
import { DOCUMENT } from '@angular/platform-browser';
3-
import { NavigationEnd, Router } from '@angular/router';
4+
import { NavigationEnd, Router, UrlSerializer } from '@angular/router';
5+
import 'rxjs/add/operator/map';
46

57
@Component({
68
selector: 'top-menu',
79
templateUrl: './top-menu.component.html'
810
})
911
export class TopMenuComponent implements AfterViewInit {
10-
public isShown: boolean = false;
12+
public isShown = false;
13+
public appUrl: string;
14+
public appHash: string;
15+
public currentVersion: string;
16+
public previousDocs: string[] = [];
17+
public isLocalhost = false;
1118

12-
private renderer: Renderer;
13-
private document: any;
14-
private router: Router;
15-
16-
public constructor(renderer: Renderer, @Inject(DOCUMENT) document: any, router: Router) {
17-
this.router = router;
18-
this.renderer = renderer;
19-
this.document = document;
19+
public constructor(private renderer: Renderer,
20+
@Inject(DOCUMENT) private document: any,
21+
private router: Router,
22+
private http: Http) {
2023
}
2124

2225
public ngAfterViewInit(): any {
2326
// todo: remove this sh**
24-
const getUrl = (router: Router) => router.routerState.snapshot.url.slice(0, router.routerState.snapshot.url.indexOf('#'));
27+
this.isLocalhost = location.hostname === 'localhost';
28+
const getUrl = (router: Router) => {
29+
const indexOfHash = router.routerState.snapshot.url.indexOf('#');
30+
31+
return router.routerState.snapshot.url.slice(0, indexOfHash);
32+
};
2533
let _prev = getUrl(this.router);
2634
this.router.events.subscribe((event: any) => {
27-
let _cur = getUrl(this.router);
35+
const _cur = getUrl(this.router);
36+
this.appHash = location.hash === '#/' ? '' : location.hash;
2837
if (event instanceof NavigationEnd && _cur !== _prev) {
2938
_prev = _cur;
3039
this.toggle(false);
3140
}
3241
});
42+
43+
this.http.get('assets/json/versions.json')
44+
.map(res => res.json())
45+
.subscribe((data: any) => {
46+
this.previousDocs = data;
47+
});
48+
this.http.get('assets/json/current-version.json')
49+
.map(res => res.json())
50+
.subscribe((data: any) => {
51+
this.currentVersion = data.version;
52+
});
53+
54+
this.appUrl = location.protocol + '//' + location.hostname + (this.isLocalhost ? ':' + location.port + '/' : '/');
3355
}
3456

3557
public toggle(isShown?: boolean): void {

demo/src/app/getting-started/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ You will need bootstrap styles (Bootstrap 3)
3535
Or Bootstrap 4
3636
```
3737
<!--- index.html -->
38-
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
38+
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
3939
```
4040
To enable bootstrap 4 theme templates in ngx-bootstrap, please read
4141
[here](https://github.com/valor-software/ngx-bootstrap/blob/development/docs/getting-started/bootstrap4.md)

demo/src/assets/css/style.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,17 @@ a:hover {
5252
float: left;
5353
}
5454

55+
#top-menu .prev-docs {
56+
position: relative;
57+
}
58+
#top-menu .prev-docs .dropdown-toggle {
59+
color: #fff;
60+
font-size: 18px;
61+
padding-top: 22px;
62+
cursor: pointer;
63+
}
64+
65+
5566
#top-menu .title {
5667
border-right: 1px solid #191924;
5768
min-width: 270px;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"1.8.1"}

demo/src/assets/json/versions.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"version":"Current","url":"ngx-bootstrap","unprefixedUrl":""},{"version":"1.8.5","url":"ngx-bootstrap/old/1.8.5","unprefixedUrl":"old/1.8.5"}]

demo/src/index-bs4.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<link href="https://fonts.googleapis.com/css?family=Roboto:400,300,700" rel="stylesheet" type="text/css">
1717

1818
<!--link to bootstrap.css v4.0.0-alpha-->
19-
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">
19+
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">
2020
<!--<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">-->
2121
<link rel="stylesheet" href="assets/css/glyphicons.css">
2222
<link rel="stylesheet" href="assets/css/style.css">

demo/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
<!--link to bootstrap.css-->
2121
<!--<script>window.__theme = 'bs4';</script>-->
22-
<!--<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet">-->
22+
<!--<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet">-->
2323
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
2424
<link rel="stylesheet" href="assets/css/style.css">
2525
<link rel="stylesheet" href="assets/css/prettify-angulario.css">

package.json

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
"description": "Native Angular Bootstrap Components",
55
"private": true,
66
"scripts": {
7-
"lite-server": "lite-server -c demo/bs-config.js",
7+
"lite-server": "lite-server -c scripts/bs-config.js",
88
"typedoc": "typedoc --exclude '**/*.spec.ts' ./src/",
99
"demo.docs": "node scripts/docs/get-doc.js",
10-
"demo.serve": "run-s build link demo.docs demo.build lite-server",
11-
"demo.gh-pages": "run-s build demo.docs demo.build demo.deploy",
10+
"demo.serve": "run-s build link demo.docs demo.build docs.archive lite-server",
11+
"demo.serve-fast": "run-s build link demo.docs demo.build-fast docs.archive lite-server",
12+
"demo.gh-pages": "run-s build demo.docs demo.build docs.archive demo.deploy",
1213
"demo.build": "ng build -prod --aot --build-optimizer && npm run generate-bs4",
13-
"demo.deploy": "gh-pages -d demo/dist",
14-
"demo-beta-deploy": "gh-pages -d demo/dist -r git@github.com:valorkin/ngx-bootstrap.git -b gh-pages",
14+
"demo.build-fast": "ng build && npm run generate-bs4",
15+
"demo.deploy": "gh-pages -d gh-pages",
16+
"demo-beta-deploy": "gh-pages -d gh-pages -r git@github.com:valorkin/ngx-bootstrap.git -b gh-pages",
17+
"docs.archive": "npm run docs.fetch && node scripts/archive.js",
18+
"docs.fetch": "node scripts/fetch-docs.js",
1519
"link": "ngm link -p src --here",
1620
"lint": "exit 0",
1721
"disable-lint": "tslint \"**/*.ts\" -c tslint.json --fix --type-check -t prose -e \"node_modules/**\" -e \"dist/**\" -e \"temp/**\" -e \"scripts/docs/**\"",
@@ -88,7 +92,6 @@
8892
"core-js": "^2.4.1",
8993
"cpy": "5.1.0",
9094
"cpy-cli": "1.0.1",
91-
"del-cli": "1.1.0",
9295
"gh-pages": "1.0.0",
9396
"gitignore-to-glob": "0.3.0",
9497
"google-code-prettify": "1.0.5",

scripts/archive.js

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const fs = require('fs-extra');
2+
const path = require('path');
3+
4+
const ghPagesDir = 'gh-pages/';
5+
const oldVersionDir = 'gh-pages/old/';
6+
const versionsFilePath = 'assets/json/versions.json';
7+
const currentVersionFilePath = 'assets/json/current-version.json';
8+
9+
const demoSrcDir = 'demo/src';
10+
const demoDistDir = 'demo/dist';
11+
const hostname = 'ngx-bootstrap';
12+
13+
let prevVersion;
14+
const newVersion = require('../package.json').version;
15+
16+
if (!fs.existsSync(ghPagesDir)) {
17+
throw new Error('gh-pages dir wasn\'t found. Run `npm run docs.fetch`');
18+
}
19+
20+
if (!fs.existsSync(demoDistDir)) {
21+
throw new Error('demo/dist dir wasn\'t found. Run `npm run demo.build`');
22+
}
23+
24+
try {
25+
prevVersion = require(path.join('../', ghPagesDir, currentVersionFilePath)).version;
26+
} catch (e) {
27+
prevVersion = require(path.join('../', demoSrcDir, currentVersionFilePath)).version;
28+
}
29+
30+
console.log('Previous version:', prevVersion);
31+
console.log('New version:', newVersion);
32+
const isVersionChanged = prevVersion !== newVersion;
33+
34+
35+
fs.readdir('gh-pages')
36+
// filter files to operate on
37+
.then(filterFileToMove)
38+
// for local development, if version not changed, clean gh-pages folder
39+
.then(files => {
40+
if (isVersionChanged) {
41+
return files;
42+
}
43+
console.log('Version hasn\'t changed. Current gh-pages version will be replaced with the one from demo/dist');
44+
return Promise.all(files.map(file => fs.remove(path.join(ghPagesDir, file))))
45+
.then(() => files)
46+
})
47+
// move old files to corresponding folder, skip for local dev
48+
.then(files => {
49+
if (!isVersionChanged) {
50+
return files;
51+
}
52+
53+
fs.ensureDirSync(path.join(oldVersionDir, prevVersion));
54+
55+
return Promise.all(files
56+
.map(file => ({
57+
from: path.join(ghPagesDir, file),
58+
to: path.join(oldVersionDir, prevVersion, file)
59+
}))
60+
.map((move) => fs.rename(move.from, move.to)));
61+
})
62+
// copy demo dist to gh-pages folder
63+
.then(() => fs.copy(demoDistDir, ghPagesDir))
64+
// generate new version json files
65+
.then(() => {
66+
if (isVersionChanged) {
67+
return generateJson();
68+
}
69+
})
70+
.catch(console.error.bind(console));
71+
72+
function filterFileToMove(files) {
73+
return files.filter((file) => file !== 'old' && file !== '.git');
74+
}
75+
76+
function generateJson() {
77+
return fs.readdir(oldVersionDir)
78+
.then(files => {
79+
let savedVersions = files.map(file => ({
80+
version: file,
81+
url: hostname + '/old/' + file,
82+
unprefixedUrl: 'old/' + file
83+
}));
84+
85+
savedVersions.unshift({version: 'Current', url: hostname, unprefixedUrl: ''});
86+
87+
return savedVersions;
88+
})
89+
.then(versions => {
90+
const content = JSON.stringify(versions);
91+
92+
return Promise
93+
.all(versions.map((ver) => {
94+
if (ver.version === 'Current') {
95+
return Promise.resolve();
96+
}
97+
98+
const _path = path.join(oldVersionDir, ver.version, versionsFilePath);
99+
fs.ensureFileSync(_path);
100+
return writeFile(_path, content);
101+
}))
102+
.then(() => writeFile(path.join(ghPagesDir, versionsFilePath), content))
103+
.then(() => writeFile(path.join(ghPagesDir, currentVersionFilePath), JSON.stringify({version: newVersion})))
104+
.then(() => writeFile(path.join(demoSrcDir, currentVersionFilePath), JSON.stringify({version: newVersion})));
105+
});
106+
}
107+
108+
function writeFile(path, content) {
109+
return fs.writeFile(path, content, 'utf8');
110+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
"port": 4200,
33
"server": {
4-
"baseDir": "./demo/dist",
4+
"baseDir": "./gh-pages",
55
middleware : { 1 : require('compression')()}
66
}
77
};

scripts/fetch-docs.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const fs = require('fs-extra');
2+
const exec = require('child_process').exec;
3+
4+
if (!fs.existsSync('gh-pages')) {
5+
console.log('Cloning the latest version of gh-pages');
6+
runCmd("git clone -b gh-pages --single-branch --depth 1 git@github.com:valor-software/ngx-bootstrap.git gh-pages");
7+
return;
8+
}
9+
console.log('Pulling the latest version of gh-pages');
10+
runCmd("cd gh-pages && git pull && cd ../");
11+
12+
function runCmd(cmd) {
13+
exec(cmd, function (err) {
14+
if (err) console.log('exec err: ' + err);
15+
console.log('Done');
16+
});
17+
}

0 commit comments

Comments
 (0)