Мне нужно отобразить версию git на моем приложении angular2 о странице. Проект основан на angular -cli.
Как можно построить расширение, чтобы версия git была помещена, например, в environment.ts
или в другое место, доступное для приложения?
Мне нужно отобразить версию git на моем приложении angular2 о странице. Проект основан на angular -cli.
Как можно построить расширение, чтобы версия git была помещена, например, в environment.ts
или в другое место, доступное для приложения?
Как подсказал @Yuri, я смог решить эту проблему с помощью сценариев npm
.
Определил git.version.ts
в корне проекта angular-cli:
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",
...
},
Другие ответы были полезны, но я предпочел более простой, прямой подход. Здесь мой.
Запустите npm install git-describe --save-dev
. Затем добавьте 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
или где - нибудь еще вы хотели бы использовать его.
Мне нравится, чтобы все было просто. Можете добавить в свой 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 лично.
Я пошел с модифицированной версией Вильмантаса Баранаускаса
Я переместил src/index.html
в src/index.base.html
и добавил пустой <meta name="revision" content="">
внутри HEAD
Пример:
<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
Я сделал это, сгенерировав сценарий prebuild, который запускается после postinstall и запускается перед любым связанным сценарием
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
У меня немного другой подход, вдохновленный ответами repo SebaArce и Jeroen, в главном каталоге проекта:
npm install git-rev-sync --save
(эта библиотека предоставляет доступ к хешу и имени ветки)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);
Просто установите этот пакет git-revision-webpack-plugin
Простой плагин webpack, который генерирует файлы VERSION и COMMITHASH во время сборки на основе локального репозитория git.
Пример кода:
Внутри вашего webpack.config.js
(или любого файла dev-prod)
const GitRevisionPlugin = require('git-revision-webpack-plugin');
const gitRevisionPlugin = new GitRevisionPlugin();
plugins: [
new DefinePlugin({
'VERSION': JSON.stringify(gitRevisionPlugin.version()),
'COMMITHASH': JSON.stringify(gitRevisionPlugin.commithash()),
'BRANCH': JSON.stringify(gitRevisionPlugin.branch()),
}),
]
В вашем шаблоне (Angular):
{{ VERSION }}
{{ COMMITHASH }}
{{ BRANCH }}
Для угловых 6
1 Установите git-description как зависимость для разработчиков
npm i git-describe -s
2 В вашем корневом проекте создайте файл grab-git-info.js
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);
Результатом скрипта grab-git-info.js будет файл 'git-version.json в каталоге /src/, который будет содержать всю информацию о git, необходимую нашему приложению.
Чтобы иметь возможность импортировать файл json (или любой другой файл json), нам нужно добавить файл определения, объявляющий добавленный модуль, чтобы компилятор Typescript распознал его.
/src/typings.d.ts:
declare module '*.json' {
const value: any;
export default value;
}
С этого момента вы можете импортировать любой файл json, расположенный в /src, как модуль!
В вашем компоненте вы можете импортировать этот JSON
import * as data from '../../../git-version.json';
...
public git = data;
В HTML
Rev: {{git.hash}}
Наконец добавьте и самое главное, запустите скрипт перед сборкой
В package.json добавьте:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "node grab-git-info && ng build",
И запустите приложение с
npm run build
Используйте gulp задачу с помощью gulp -replace и git -rev-sync, чтобы добавить хэш и ветку в сборке:
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