Skip to content

Commit

Permalink
lib/reference.js: async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
samuela committed Oct 17, 2021
1 parent 6aca353 commit 997d6ab
Showing 1 changed file with 94 additions and 112 deletions.
206 changes: 94 additions & 112 deletions lib/reference.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,104 @@
var util = require("util");
var NodeGit = require("../");
var LookupWrapper = NodeGit.Utils.lookupWrapper;
const util = require("util");
const NodeGit = require("../");
const LookupWrapper = NodeGit.Utils.lookupWrapper;

var Reference = NodeGit.Reference;
var Branch = NodeGit.Branch;
const Reference = NodeGit.Reference;
const Branch = NodeGit.Branch;

/**
* Retrieves the reference by it's short name
* @async
* @param {Repository} repo The repo that the reference lives in
* @param {String|Reference} id The reference to lookup
* @param {Function} callback
* @return {Reference}
*/
* Retrieves the reference by it's short name
* @async
* @param {Repository} repo The repo that the reference lives in
* @param {String|Reference} id The reference to lookup
* @param {Function} callback
* @return {Reference}
*/
Reference.dwim = LookupWrapper(Reference, Reference.dwim);

/**
* Retrieves the reference pointed to by the oid
* @async
* @param {Repository} repo The repo that the reference lives in
* @param {String|Reference} id The reference to lookup
* @param {Function} callback
* @return {Reference}
*/
* Retrieves the reference pointed to by the oid
* @async
* @param {Repository} repo The repo that the reference lives in
* @param {String|Reference} id The reference to lookup
* @param {Function} callback
* @return {Reference}
*/
Reference.lookup = LookupWrapper(Reference);

/**
* Returns true if this reference is not symbolic
* @return {Boolean}
*/
Reference.prototype.isConcrete = function() {
Reference.prototype.isConcrete = function () {
return this.type() == Reference.TYPE.DIRECT;
};

/**
* Returns if the ref is pointed at by HEAD
* @return {Boolean}
*/
Reference.prototype.isHead = function() {
Reference.prototype.isHead = function () {
return Branch.isHead(this);
};

/**
* Returns true if this reference is symbolic
* @return {Boolean}
*/
Reference.prototype.isSymbolic = function() {
Reference.prototype.isSymbolic = function () {
return this.type() == Reference.TYPE.SYMBOLIC;
};

/**
* Returns true if this reference is valid
* @return {Boolean}
*/
Reference.prototype.isValid = function() {
Reference.prototype.isValid = function () {
return this.type() != Reference.TYPE.INVALID;
};

/**
* Returns the name of the reference.
* @return {String}
*/
Reference.prototype.toString = function() {
return this.name();
Reference.prototype.toString = function () {
return this.name();
};

const getTerminal = (repo, refName, depth = 10, prevRef = null) => {
const getTerminal = async (repo, refName, depth = 10, prevRef = null) => {
if (depth <= 0) {
return Promise.resolve({
return {
error: NodeGit.Error.CODE.ENOTFOUND,
out: prevRef
});
out: prevRef,
};
}

return NodeGit.Reference.lookup(repo, refName)
.then((ref) => {
if (ref.type() === NodeGit.Reference.TYPE.DIRECT) {
return {
error: NodeGit.Error.CODE.OK,
out: ref
};
} else {
return getTerminal(repo, ref.symbolicTarget(), depth - 1, ref)
.then(({ error, out }) => {
if (error === NodeGit.Error.CODE.ENOTFOUND && !out) {
return { error, out: ref };
} else {
return { error, out };
}
});
}
})
.catch((error) => {
try {
const ref = await NodeGit.Reference.lookup(repo, refName);
if (ref.type() === NodeGit.Reference.TYPE.DIRECT) {
return {
error: error.errno,
out: null
error: NodeGit.Error.CODE.OK,
out: ref,
};
});
} else {
const { error, out } = await getTerminal(
repo,
ref.symbolicTarget(),
depth - 1,
ref
);
if (error === NodeGit.Error.CODE.ENOTFOUND && !out) {
return { error, out: ref };
} else {
return { error, out };
}
}
} catch (error) {
return {
error: error.errno,
out: null,
};
}
};

const getSignatureForReflog = (repo) => {
Expand All @@ -105,8 +107,9 @@ const getSignatureForReflog = (repo) => {
return Promise.resolve(NodeGit.Signature.now(name, email));
}

return NodeGit.Signature.default(repo)
.catch(() => NodeGit.Signature.now("unknown", "unknown"));
return NodeGit.Signature.default(repo).catch(() =>
NodeGit.Signature.now("unknown", "unknown")
);
};

/**
Expand All @@ -120,69 +123,48 @@ const getSignatureForReflog = (repo) => {
* @param {String} logMessage The reflog message to be writted
* @param {Signature} signature Optional signature to use for the reflog entry
*/
Reference.updateTerminal = function (
Reference.updateTerminal = async function (
repo,
refName,
oid,
logMessage,
signature
) {
let signatureToUse;
let promiseChain = Promise.resolve();

if (!signature) {
promiseChain = promiseChain
.then(() => getSignatureForReflog(repo))
.then((sig) => {
signatureToUse = sig;
return Promise.resolve();
});
const signatureToUse = !signature ? await getSignatureForReflog(repo)
: signature;

const { error, out } = await getTerminal(repo, refName);
if (error === NodeGit.Error.CODE.ENOTFOUND && out) {
await NodeGit.Reference.create(
repo,
out.symbolicTarget(),
oid,
0,
logMessage
);
} else if (error === NodeGit.Error.CODE.ENOTFOUND) {
await NodeGit.Reference.create(repo, refName, oid, 0, logMessage);
} else {
signatureToUse = signature;
await NodeGit.Reference.createMatching(
repo,
out.name(),
oid,
1,
out.target(),
logMessage
);
}

return promiseChain
.then(() => getTerminal(repo, refName))
.then(({ error, out }) => {
if (error === NodeGit.Error.CODE.ENOTFOUND && out) {
return NodeGit.Reference.create(
repo,
out.symbolicTarget(),
oid,
0,
logMessage
);
} else if (error === NodeGit.Error.CODE.ENOTFOUND) {
return NodeGit.Reference.create(
repo,
refName,
oid,
0,
logMessage
);
} else {
return NodeGit.Reference.createMatching(
repo,
out.name(),
oid,
1,
out.target(),
logMessage
);
}
})
.then(() => NodeGit.Reflog.read(repo, refName))
.then((reflog) => {
// Janky, but works. Ideally, we would want to generate the correct reflog
// entry in the first place, rather than drop the most recent entry and
// write the correct one.
// NOTE: There is a theoretical race condition that could happen here.
// We may want to consider some kind of transactional logic to make sure
// that the reflog on disk isn't modified before we can write back.
reflog.drop(0, 1);
reflog.append(oid, signatureToUse, logMessage);
return reflog.write();
});
const reflog = await NodeGit.Reflog.read(repo, refName);

// Janky, but works. Ideally, we would want to generate the correct reflog
// entry in the first place, rather than drop the most recent entry and
// write the correct one.
// NOTE: There is a theoretical race condition that could happen here.
// We may want to consider some kind of transactional logic to make sure
// that the reflog on disk isn't modified before we can write back.
reflog.drop(0, 1);
reflog.append(oid, signatureToUse, logMessage);
return await reflog.write();
};

// Deprecated -----------------------------------------------------------------
Expand All @@ -191,14 +173,14 @@ Object.defineProperty(NodeGit.Reference.TYPE, "OID", {
get: util.deprecate(
() => NodeGit.Reference.TYPE.DIRECT,
"Use NodeGit.Reference.TYPE.DIRECT instead of NodeGit.Reference.TYPE.OID."
)
),
});

Object.defineProperty(NodeGit.Reference.TYPE, "LISTALL", {
get: util.deprecate(
() => NodeGit.Reference.TYPE.ALL,
"Use NodeGit.Reference.TYPE.ALL instead of NodeGit.Reference.TYPE.LISTALL."
)
),
});

NodeGit.Reference.NORMALIZE = {};
Expand All @@ -207,7 +189,7 @@ Object.keys(NodeGit.Reference.FORMAT).forEach((key) => {
get: util.deprecate(
() => NodeGit.Reference.FORMAT[key],
`Use NodeGit.Reference.FORMAT.${key} instead of ` +
`NodeGit.Reference.NORMALIZE.REF_FORMAT_${key}.`
)
`NodeGit.Reference.NORMALIZE.REF_FORMAT_${key}.`
),
});
});

0 comments on commit 997d6ab

Please sign in to comment.