gitea-repository-provider
Version:
repository provider for gitea
156 lines (141 loc) • 4.03 kB
JavaScript
import { matcher } from "matching-iterator";
import {
StreamContentEntry,
BufferContentEntry,
ContentEntry,
CollectionEntry
} from "content-entry";
import {
count_attribute_writable,
string_attribute_writable,
boolean_attribute_writable
} from "pacc";
import { Branch, CommitResult } from "repository-provider";
import { join } from "./util.mjs";
/**
*
*
*/
export class GiteaBranch extends Branch {
static attributes = {
...super.attributes,
displayName: {
...Branch.attributes.displayName,
externalName: "full_name"
},
user_can_merge: boolean_attribute_writable,
user_can_push: boolean_attribute_writable,
required_approvals: count_attribute_writable,
enable_status_check: boolean_attribute_writable,
effective_branch_protection_name: string_attribute_writable
};
async *entries(patterns) {
const { json } = await this.provider.fetchJSON(
join("repos", this.repository.fullName, "git/trees", await this.refId) +
"?recursive=true"
);
for (const entry of matcher(json.tree, patterns, {
name: "path"
})) {
const options = { mode: entry.mode };
yield entry.type === "tree"
? new CollectionEntry(entry.path, options)
: this.name === "master"
? new StreamContentEntry(entry.path, options, async entry => {
const url = join(
"repos",
this.repository.fullName,
"raw",
entry.name
);
const result = await this.provider.fetch(url);
return result.body;
})
: new BufferContentEntry(entry.path, options, async entry => {
const url = join(
"repos",
this.repository.fullName,
"contents",
entry.name + "?ref=" + this.name
);
const result = await this.provider.fetch(url);
const body = await result.json();
return Buffer.from(body.content, "base64");
});
}
}
async removeEntries(entries) {
for await (const entry of entries) {
await this.provider.fetch(
join("repos", this.repository.fullName, "contents", entry.name),
{
method: "DELETE",
body: JSON.stringify({ branch: this.name, message: "", sha: "" })
}
);
}
}
async sha(path) {
const { json } = await this.provider.fetchJSON(
join("repos", this.repository.fullName, "contents", path) +
"#" +
this.name
);
return json.sha;
}
/**
* Writes content into the branch.
* @param {ContentEntry} entry
* @param {string} message
* @return {Promise<ContentEntry>} written content with sha values set
*/
async writeEntry(entry, message) {
const content = await entry.string;
const owner = this.repository.owner;
const date = new Date();
const body = JSON.stringify({
message,
branch: this.name,
content: btoa(content),
author: {
name: owner.name,
email: owner.email
},
sha: await this.sha(entry.name),
dates: {
author: date.toISOString(),
committer: date.toISOString()
},
signoff: false
});
const { json, response } = await this.provider.fetchJSON(
join("repos", this.repository.fullName, "contents", entry.name),
{
method: "PUT",
body
}
);
if (!response.ok) {
console.error(body);
throw new Error(response.statusText);
}
entry.sha = json.sha;
return entry;
}
/**
* Commit entries.
* @param {string} message commit message
* @param {ContentEntry[]} entries content to be commited
* @param {Object} [options]
* @return {Promise<CommitResult>}
*/
async commit(message, entries, options) {
const updates = await Promise.all(
entries.map(entry => this.writeEntry(entry, message))
);
// TODO hack
return {
ref: `refs/heads/${this.name}`
};
}
}