11'use strict' ;
22
33const { execFile } = require ( 'child_process' ) ;
4+ const { promisify } = require ( 'util' ) ;
5+
6+ const execFileAsync = promisify ( execFile ) ;
47
58/**
69 * Fetches and enriches git metadata with information from the local git repository
@@ -15,26 +18,21 @@ const { execFile } = require('child_process');
1518 * @param {string } [git.head.message] - Commit message
1619 * @param {string } [git.branch] - Branch name
1720 * @param {Array<{name: string, url: string}> } [git.remotes] - Git remotes
18- * @param {Function } cb - Callback function (err, enrichedGit)
19- * @returns {void }
20- * @throws {Error } Via callback if required fields are missing or git commands fail
21+ * @returns {Promise<Object> } Enriched git metadata object
22+ * @throws {Error } If required fields are missing or git commands fail
2123 */
22- function fetchGitData ( git , cb ) {
23- if ( ! cb ) {
24- throw new Error ( 'fetchGitData requires a callback' ) ;
25- }
26-
24+ async function fetchGitData ( git ) {
2725 // -- Malformed/undefined git object
2826 if ( typeof git === 'undefined' ) {
29- return cb ( new Error ( 'No options passed' ) ) ;
27+ throw new Error ( 'No options passed' ) ;
3028 }
3129
3230 if ( ! Object . prototype . hasOwnProperty . call ( git , 'head' ) ) {
33- return cb ( new Error ( 'You must provide the head' ) ) ;
31+ throw new Error ( 'You must provide the head' ) ;
3432 }
3533
3634 if ( ! Object . prototype . hasOwnProperty . call ( git . head , 'id' ) ) {
37- return cb ( new Error ( 'You must provide the head.id' ) ) ;
35+ throw new Error ( 'You must provide the head.id' ) ;
3836 }
3937
4038 // -- Set required properties of git if they weren"t provided
@@ -56,38 +54,31 @@ function fetchGitData(git, cb) {
5654 }
5755
5856 // -- Use git?
59- execFile ( 'git' , [ 'rev-parse' , '--verify' , git . head . id ] , err => {
60- if ( err ) {
61- // git is not available...
62- git . head . author_name = git . head . author_name || 'Unknown Author' ;
63- git . head . author_email = git . head . author_email || '' ;
64- git . head . committer_name = git . head . committer_name || 'Unknown Committer' ;
65- git . head . committer_email = git . head . committer_email || '' ;
66- git . head . message = git . head . message || 'Unknown Commit Message' ;
67- return cb ( null , git ) ;
68- }
69-
70- fetchHeadDetails ( git , cb ) ;
71- } ) ;
57+ try {
58+ await execFileAsync ( 'git' , [ 'rev-parse' , '--verify' , git . head . id ] ) ;
59+ } catch {
60+ // git is not available...
61+ git . head . author_name = git . head . author_name || 'Unknown Author' ;
62+ git . head . author_email = git . head . author_email || '' ;
63+ git . head . committer_name = git . head . committer_name || 'Unknown Committer' ;
64+ git . head . committer_email = git . head . committer_email || '' ;
65+ git . head . message = git . head . message || 'Unknown Commit Message' ;
66+ return git ;
67+ }
68+ return await fetchHeadDetails ( git ) ;
7269}
7370
7471/**
7572 * Fetches the current branch name using git branch command
7673 * Sets git.branch if a valid branch is detected (excludes detached HEAD states)
7774 * @param {Object } git - Git metadata object to update
78- * @param {Function } cb - Callback function (err, git)
79- * @returns {void }
75+ * @returns {Promise<Object> } Updated git metadata object
8076 * @private
8177 */
82- function fetchBranch ( git , cb ) {
83- execFile ( 'git' , [ 'branch' ] , ( err , branches ) => {
84- if ( err ) {
85- return cb ( err ) ;
86- }
87-
88- git . branch = ( branches . match ( / ^ \* ( [ \w . / - ] + ) / m) || [ ] ) [ 1 ] ?? '' ;
89- fetchRemotes ( git , cb ) ;
90- } ) ;
78+ async function fetchBranch ( git ) {
79+ const { stdout : branches } = await execFileAsync ( 'git' , [ 'branch' ] ) ;
80+ git . branch = ( branches . match ( / ^ \* ( [ \w . / - ] + ) / m) || [ ] ) [ 1 ] ?? '' ;
81+ return await fetchRemotes ( git ) ;
9182}
9283
9384const REGEX_COMMIT_DETAILS =
@@ -97,60 +88,50 @@ const REGEX_COMMIT_DETAILS =
9788 * Fetches detailed commit information using git cat-file
9889 * Populates author, committer, and message fields in git.head
9990 * @param {Object } git - Git metadata object to update
100- * @param {Function } cb - Callback function (err, git)
101- * @returns {void }
91+ * @returns {Promise<Object> } Updated git metadata object
10292 * @private
10393 */
104- function fetchHeadDetails ( git , cb ) {
105- execFile ( 'git' , [ 'cat-file' , '-p' , git . head . id ] , ( err , response ) => {
106- if ( err ) {
107- return cb ( err ) ;
108- }
109-
110- const match = response . match ( REGEX_COMMIT_DETAILS ) ;
111- if ( ! match ) {
112- return cb ( new Error ( 'Unable to parse commit details from git cat-file output' ) ) ;
113- }
94+ async function fetchHeadDetails ( git ) {
95+ const { stdout : response } = await execFileAsync ( 'git' , [ 'cat-file' , '-p' , git . head . id ] ) ;
11496
115- const items = match . slice ( 1 ) ;
116- const fields = [ 'author_name' , 'author_email' , 'committer_name' , 'committer_email' , 'message' ] ;
117- fields . forEach ( ( field , index ) => {
118- git . head [ field ] = items [ index ] ;
119- } ) ;
97+ const match = response . match ( REGEX_COMMIT_DETAILS ) ;
98+ if ( ! match ) {
99+ throw new Error ( 'Unable to parse commit details from git cat-file output' ) ;
100+ }
120101
121- if ( git . branch ) {
122- fetchRemotes ( git , cb ) ;
123- } else {
124- fetchBranch ( git , cb ) ;
125- }
102+ const items = match . slice ( 1 ) ;
103+ const fields = [ 'author_name' , 'author_email' , 'committer_name' , 'committer_email' , 'message' ] ;
104+ fields . forEach ( ( field , index ) => {
105+ git . head [ field ] = items [ index ] ;
126106 } ) ;
107+
108+ if ( git . branch ) {
109+ return await fetchRemotes ( git ) ;
110+ } else {
111+ return await fetchBranch ( git ) ;
112+ }
127113}
128114
129115/**
130116 * Fetches git remotes using git remote -v command
131117 * Filters to only include push remotes and deduplicates entries
132118 * @param {Object } git - Git metadata object to update
133- * @param {Function } cb - Callback function (err, git)
134- * @returns {void }
119+ * @returns {Promise<Object> } Updated git metadata object
135120 * @private
136121 */
137- function fetchRemotes ( git , cb ) {
138- execFile ( 'git' , [ 'remote' , '-v' ] , ( err , remotes ) => {
139- if ( err ) {
140- return cb ( err ) ;
141- }
122+ async function fetchRemotes ( git ) {
123+ const { stdout : remotes } = await execFileAsync ( 'git' , [ 'remote' , '-v' ] ) ;
142124
143- const processed = { } ;
144- remotes . split ( '\n' ) . forEach ( remote => {
145- if ( ! / \s \( p u s h \) $ / . test ( remote ) ) {
146- return ;
147- }
125+ const processed = { } ;
126+ remotes . split ( '\n' ) . forEach ( remote => {
127+ if ( ! / \s \( p u s h \) $ / . test ( remote ) ) {
128+ return ;
129+ }
148130
149- remote = remote . split ( / \s + / ) ;
150- saveRemote ( processed , git , remote [ 0 ] , remote [ 1 ] ) ;
151- } ) ;
152- cb ( null , git ) ;
131+ remote = remote . split ( / \s + / ) ;
132+ saveRemote ( processed , git , remote [ 0 ] , remote [ 1 ] ) ;
153133 } ) ;
134+ return git ;
154135}
155136
156137/**
0 commit comments