我需要在angular2应用程序上显示关于页面的git修订版。该项目基于angular-cli。
如何扩展构建,以便将git修订版放在例如environment.ts
或应用程序可访问的其他位置?
答案 0 :(得分:38)
根据@Yuri的建议,我能够通过使用npm
脚本来解决这个问题。
在angular-cli项目的根目录中定义git.version.ts
:
import fs = require('fs');
import { Observable } from 'rxjs';
let exec = require('child_process').exec;
const revision = new Observable<string>(s => {
exec('git rev-parse --short HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
const branch = new Observable<string>(s => {
exec('git rev-parse --abbrev-ref HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
Observable
.combineLatest(revision, branch)
.subscribe(([revision, branch]) => {
console.log(`version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'`);
const content = '// this file is automatically generated by git.version.ts script\n' +
`export const versions = {version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'};`;
fs.writeFileSync(
'src/environments/versions.ts',
content,
{encoding: 'utf8'}
);
});
在package.json
中添加了预构建挂钩:
"scripts": {
"ng": "ng",
...
"start": "ng serve --proxy proxy-config.json",
"prebuild.prod": "ts-node git.version.ts",
"build.prod": "ng build -prod",
...
},
在应用程序中使用生成的src/environments/versions.ts
。
更新10/2018:以下是更易读的脚本版本,rxjs-version-agnostic:
import { writeFileSync } from 'fs';
import { dedent } from 'tslint/lib/utils';
const util = require('util');
const exec = util.promisify(require('child_process').exec);
async function createVersionsFile(filename: string) {
const revision = (await exec('git rev-parse --short HEAD')).stdout.toString().trim();
const branch = (await exec('git rev-parse --abbrev-ref HEAD')).stdout.toString().trim();
console.log(`version: '${process.env.npm_package_version}', revision: '${revision}', branch: '${branch}'`);
const content = dedent`
// this file is automatically generated by git.version.ts script
export const versions = {
version: '${process.env.npm_package_version}',
revision: '${revision}',
branch: '${branch}'
};`;
writeFileSync(filename, content, {encoding: 'utf8'});
}
createVersionsFile('src/environments/versions.ts');
注意,使用angular-cli v7.0.6时,我还必须更改package.json
中的脚本调用:
"scripts": {
...
"prebuild.prod": "ts-node -O '{\"module\": \"commonjs\"}' git.version.ts",
...
},
答案 1 :(得分:6)
git-version.js
添加到根。此代码将执行git命令并将输出写入git-version.json
文件。const childProcess = require('child_process');
const { writeFileSync } = require('fs');
const longSHA = childProcess.execSync("git rev-parse HEAD").toString().trim();
const shortSHA = childProcess.execSync("git rev-parse --short HEAD").toString().trim();
const branch = childProcess.execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
const authorName = childProcess.execSync("git log -1 --pretty=format:'%an'").toString().trim();
const commitTime = childProcess.execSync("git log -1 --pretty=format:'%cd'").toString().trim();
const commitMsg = childProcess.execSync("git log -1 --pretty=%B").toString().trim();
const totalCommitCount = childProcess.execSync("git rev-list --count HEAD").toString().trim();
const versionInfo = {
shortSHA: shortSHA,
SHA : longSHA,
branch: branch,
lastCommitAuthor: authorName,
lastCommitTime: commitTime,
lastCommitMessage: commitMsg,
lastCommitNumber: totalCommitCount
}
const versionInfoJson = JSON.stringify(versionInfo, null, 2);
writeFileSync('/src/git-version.json', versionInfoJson);
此代码将生成git-version.json
文件:-
{
"shortSHA": "0e786d4",
"SHA": "0e786d4ad3778463f6f30c28f254cc85c24eb4b3",
"branch": "master",
"lastCommitAuthor": "'saurabh'",
"lastCommitTime": "'Thu Apr 9 12:59:16 2020 +0530'",
"lastCommitMessage": "Commit message",
"lastCommitNumber": "200"
}
根据您的要求修改以上代码。
运行:node git-version.js
这将在git-version.json
目录中生成src
。
package.json
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"build.prod": "node git-version.js && ng build --prod"
}
npm run build.prod
改进代码的建议:)
答案 2 :(得分:5)
其他答案很有帮助,但我更喜欢一种更简单,直接的方法。这是我的。
运行npm install --save dev git-describe
。然后将git-version.js
添加到根目录:
// This script runs operations *synchronously* which is normally not the best
// approach, but it keeps things simple, readable, and for now is good enough.
const { gitDescribeSync } = require('git-describe');
const { writeFileSync } = require('fs');
const gitInfo = gitDescribeSync();
const versionInfoJson = JSON.stringify(gitInfo, null, 2);
writeFileSync('git-version.json', versionInfoJson);
您也可以将/git-version.json
添加到.gitignore
文件中。
更新您的package.json
,以执行以下操作:
"scripts": {
"build": "node git-version.js && ng build"
}
然后将version-info.ts
添加到项目的根目录:
export const versionInfo = (() => {
try {
// tslint:disable-next-line:no-var-requires
return require('../../git-version.json');
} catch {
// In dev the file might not exist:
return { tag: 'v0.0.0', hash: 'dev' };
}
})();
在您的import
或您想使用的其他任何地方,versionInfo
和app.component.ts
。
答案 3 :(得分:3)
我喜欢保持简单。可以添加到您的index.html:
<script>window.version = '{git-hash}';</script>
然后将postbuild
脚本添加到您的package.json
:
"postbuild": "sed -i '' \"s/{git\\-hash}/$(git rev-parse --short HEAD)/g\" dist/*/index.html"
无论如何都不优雅。我个人在window
上创建了一个对象,其中包含有关构建的各种信息(时间,版本和发行摘要链接)。
要保持更“纯净”,请将{git-hash}
字符串粘贴在environment.prod.ts
中,并对生成的所有sed
文件运行main-*.js
。
"postbuild": "sed -i '' \"s/{git\\-hash}/$(git rev-parse --short HEAD)/g\" dist/*/main-*.js"
请注意,您将始终在本地看到“ {git-hash}”,因为它仅在构建后被替换。 如果您在构建之前就将其替换,显然不能在将来的本地版本中替换它,并且肯定会无意中将其检入。
----更新----
最终创建了一个库以提取各种信息。仅最终个人使用版本,构建时间和commitTime。
答案 4 :(得分:1)
我选择了Vilmantas Baranauskas的修改版本
我已将src/index.html
移至src/index.base.html
并在HEAD中添加了空<meta name="revision" content="">
示例:
<head>
<meta charset="utf-8">
<title>MySuperAwesome Angular</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="revision" content="">
<link rel="icon" type="image/x-icon" href="favicon.ico">
然后像这样修改git.version.ts
:
import 'rxjs/add/observable/combineLatest';
import { readFileSync, writeFileSync } from 'fs';
import { join } from 'path';
import { Observable } from 'rxjs/Observable';
const indexBasePath = join(__dirname, 'src');
const exec = require('child_process').exec;
const revObs = new Observable<string>(s => {
exec('git rev-parse --short HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
const branchObs = new Observable<string>(s => {
exec('git rev-parse --abbrev-ref HEAD',
function (error: Error, stdout: Buffer, stderr: Buffer) {
if (error !== null) {
console.log('git error: ' + error + stderr);
}
s.next(stdout.toString().trim());
s.complete();
});
});
Observable
.combineLatest(revObs, branchObs)
.subscribe(([revision, branch]) => {
console.log(`revision: '${revision}', branch: '${branch}'`);
const baseHTML = readFileSync(join(indexBasePath, 'index.base.html'), 'utf8');
const html = baseHTML
.replace('<meta name="revision" content="">', `<meta name="revision" content="${ revision }">`);
writeFileSync(
join(indexBasePath, 'index.html'),
html,
{ encoding: 'utf8' }
);
});
在这个例子中我只提出了修订版,但你可以更彻底,并将分支和版本放在你的html HEAD部分
答案 5 :(得分:1)
受主项目目录中的答案repo Seba Arce和Jeroen启发,我有一些不同的方法:
npm install git-rev-sync --save
(此lib赋予哈希和分支名称的访问权限)git-version-gen.js
const git = require('git-rev-sync');
const { writeFileSync } = require('fs');
const gitInfo = { commit: git.short(), commitLong: git.long(), branch: git.branch() };
const ts = 'export const gitVersion = ' + JSON.stringify(gitInfo, null, 2);
writeFileSync('src/environments/git-version.ts', ts);
package.json
的{{1}}中添加scripts
"build": "node git-version-gen.js && ng build ..."
如下使用它
app.component.ts
使用此功能有什么好处?
我们在此处创建import { gitVersion } from '../../../environments/git-version';
// ...
constructor() {
console.log(`GIT branch:`,gitVersion.branch);
console.log(`GIT commit:`,gitVersion.commit);
}
文件,因此这是TypeScript,而不是.json-与您的环境文件类似,这将打开您的代码编辑器(例如VSCode)的支持
您具有提交哈希nad分支名称的权限(lib src/environments/git-version.ts
没有为分支名称赋予acces)
如果您提交生成的git-describe
文件而不是将其放入git-version.ts
,则项目将在没有构建的情况下运行(例如,由.gitignore
),并且新开发人员将不会感到困惑缺少一些“神秘”文件...-但是选择取决于您。
跨平台-已在Azure(windows),MacOs(类似于Linux)上进行测试
答案 6 :(得分:0)
对于角度6
1将git-describe安装为开发依赖项
With ActiveDocument
.Fields.Add Range:=Selection.Sections.First.Footers(wdHeaderFooterPrimary).Range.Characters.Last, _
Type:=wdFieldEmpty, Text:="PRINTDATE \@""'This document was last printed on 'DD MMM YYYY""", PreserveFormatting:=False
End With
2在您的根项目中,创建一个grab-git-info.js
npm i git-describe -s
grab-git-info.js脚本的输出将是/ src /下的“ git-version.json”文件,其中将包含我们应用程序所需的所有git信息。
为了能够导入json文件(或其他任何json文件),我们需要添加一个定义文件来声明添加的模块,以便Typescript编译器能够识别它。
/src/typings.d.ts:
const { gitDescribeSync } = require('git-describe');
const { writeFileSync } = require('fs');
const path = require('path');
const info = gitDescribeSync();
const infoJson = JSON.stringify(info, null, 2);
writeFileSync(path.join(__dirname, '/src/git-version.json'), infoJson);
从这一点开始,您可以将/ src下的任何json文件作为模块导入!
在您的组件中,您可以导入此json
declare module '*.json' {
const value: any;
export default value;
}
在html
中 import * as data from '../../../git-version.json';
...
public git = data;
最后 添加,最重要的是,在构建之前运行脚本
在package.json中添加:
Rev: {{git.hash}}
并使用
运行该应用"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "node grab-git-info && ng build",
答案 7 :(得分:0)
我通过生成在安装后运行并在任何角度相关的脚本之前运行的预构建脚本来做到这一点
const fs = require('fs');
const git = require('git-rev-sync');
var mkdirp = require('mkdirp');
const releaseTag = git.tag();
const template = `export const gitTag = '${releaseTag}';\n`;
mkdirp('./generated', function(err) {
fs.writeFileSync('./generated/git-tag.ts', template, { encoding: 'UTF-8' });
});
生成了git-tag.ts文件:
export const gitTag = 'xxxxxxx';
现在您只需在组件中使用
import { gitTag } from '[pathToRoot]/generated/git-tag';
还添加 .gitignore
generated
答案 8 :(得分:-1)
使用gulp-task和git-rev-sync使用gulp任务在build上添加hash和branch:
1)创建gulp任务
var gulp = require('gulp'),
replace = require('gulp-replace'),
git = require('git-rev-sync'),
gulp.task('git', function () {
gulp.src('src/index.html')
.pipe(replace('{{git-branch}}', git.branch()))
.pipe(replace('{{git-hash}}', git.short()))
.pipe(gulp.dest('src/'))
});
// Build Tasks
gulp.task('build', ['git']);
2)将以下代码添加到index.html:
{{git-branch}}@{{git-hash}}
3)运行
gulp build