Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect package data from specific tags #260

Merged
merged 7 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions src/controllers/postPackagesPackageNameVersions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ module.exports = {
summary: "Creates a new package version.",
responses: {
201: {
description: "The package details indicating success.",
content: {
"application/json": "$packageObjectFull",
},
description: "An object with a key 'message' indicating what version has been published.",
},
},
},
Expand All @@ -37,9 +34,30 @@ module.exports = {
packageName: (context, req) => {
return context.query.packageName(req);
},
tag: (context, req) => {
return context.query.tag(req);
}
},
async postReturnHTTP(req, res, context, obj) {
// We use postReturnHTTP to ensure the user doesn't wait on these other actions

// Lets bail early in case these values don't exist.
// Such as the original request failing

if (typeof obj?.webhook?.pack !== "string" || typeof obj?.webhook?.user !== "string") {
// This data isn't defined, and we cannot work with it
return;
}

if (
typeof obj?.featureDetection?.user !== "string" ||
typeof obj?.featureDetection?.ownerRepo !== "string" ||
typeof obj?.featureDetection?.service !== "string"
) {
// This data isn't defined, and we cannot work with it
return;
}

await context.webhook.alertPublishVersion(
obj.webhook.pack,
obj.webhook.user
Expand Down Expand Up @@ -145,6 +163,7 @@ module.exports = {
let packMetadata = await context.vcs.newVersionData(
user.content,
ownerRepo,
params.tag,
"git"
);

Expand All @@ -153,7 +172,11 @@ module.exports = {
if (!packMetadata.ok) {
const sso = new context.sso();

return sso.notOk().addContent(packMetadata).assignCalls(callStack);
return sso
.notOk()
.addContent(packMetadata)
.addMessage(packMetadata.content) // Trust the output of VCS as an error message
.assignCalls(callStack);
}

const newName = packMetadata.content.name;
Expand Down Expand Up @@ -267,6 +290,6 @@ module.exports = {
ownerRepo: ownerRepo,
};

return sso.isOk().addContent(addVer.content);
return sso.isOk().addContent(addVer).addMessage(addVer.content);
},
};
48 changes: 36 additions & 12 deletions src/vcs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* function.
*/

const semver = require("semver");
const query = require("./query_parameters/index.js").logic;
const utils = require("./utils.js");
const constructNewPackagePublishData = require("./models/constructNewPackagePublishData.js");
Expand Down Expand Up @@ -123,28 +124,36 @@ async function newPackageData(userObj, ownerRepo, service) {
.build();
}

let pack = await provider.packageJSON(userObj, ownerRepo);
// We will get tags first so that we can utilize specific tags when asking
// for further information about a package, rather than use the default branch
// information.
// See: https://github.com/pulsar-edit/package-backend/issues/205

if (!pack.ok) {
const tags = await provider.tags(userObj, ownerRepo);

if (!tags.ok) {
return new ServerStatus()
.notOk()
.setContent(`Failed to get gh package for ${ownerRepo} - ${pack.short}`)
.setShort("Bad Package")
.setContent(`Failed to get gh tags for ${ownerRepo} - ${tags.short}`)
.setShort("Server Error")
.build();
}

const tags = await provider.tags(userObj, ownerRepo);
// Sort the tags into descending order
tags.content.sort((a, b) => { return semver.rcompare(a.name, b.name)} );

if (!tags.ok) {
let pack = await provider.packageJSON(userObj, ownerRepo, tags.content[0]?.name);

if (!pack.ok) {
return new ServerStatus()
.notOk()
.setContent(`Failed to get gh tags for ${ownerRepo} - ${tags.short}`)
.setShort("Server Error")
.setContent(`Failed to get gh package for ${ownerRepo} - ${pack.short}`)
.setShort("Bad Package")
.build();
}

// Now to get our Readme
const readme = await provider.readme(userObj, ownerRepo);
const readme = await provider.readme(userObj, ownerRepo, tags.content[0]?.name);

if (!readme.ok) {
return new ServerStatus()
Expand Down Expand Up @@ -222,13 +231,15 @@ async function newPackageData(userObj, ownerRepo, service) {
* @param {object} userObj - The Full User Object as returned by `auth.verifyAuth()`
* @param {string} ownerRepo - The Owner Repo Combo of the package affected.
* Such as `pulsar-edit/pulsar`
* @param {string} tagRef - The version number or ref where data should be sought
* from the remote resource.
* @param {string} service - The service to use as expected to be returned
* by `vcs.determineProvider()`. Currently should be hardcoded to "git"
* @returns {SSO_VCS_newVersionData} A Server Status Object, which when `ok: true`
* returns all data that would be needed to update a package on the DB, and
* upload a new version.
*/
async function newVersionData(userObj, ownerRepo, service) {
async function newVersionData(userObj, ownerRepo, tagRef, service) {
// Originally when publishing a new version the responsibility to collect
// all package data fell onto the package_handler itself
// Including collecting readmes and tags, now this function should encapsulate
Expand All @@ -244,7 +255,20 @@ async function newVersionData(userObj, ownerRepo, service) {
provider = new GitHub();
}

let pack = await provider.packageJSON(userObj, ownerRepo);
let exists = await provider.exists(userObj, ownerRepo);

if (!exists.ok) {
// Could be due to an error, or it doesn't exist at all.
// For now until we support custom error messages will do a catch all
// return.
return new ServerStatus()
.notOk()
.setContent(`Failed to get repo: ${ownerRepo} - ${exists.short}`)
.setShort("Bad Repo")
.build();
}

let pack = await provider.packageJSON(userObj, ownerRepo, tagRef);

if (!pack.ok) {
return {
Expand All @@ -257,7 +281,7 @@ async function newVersionData(userObj, ownerRepo, service) {
// Now we will also need to get the packages data to update on the DB
// during verison pushes.

let readme = await provider.readme(userObj, ownerRepo);
let readme = await provider.readme(userObj, ownerRepo, tagRef);

if (!readme.ok) {
return {
Expand Down
59 changes: 48 additions & 11 deletions src/vcs_providers/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

const Git = require("./git.js");
const CSON = require("cson");
const semver = require("semver");

/**
* @class GitHub
Expand Down Expand Up @@ -172,12 +173,19 @@
* the specified users credentials.
* @param {object} userObj - The Raw User Object after verification.
* @param {string} ownerRepo - The `owner/repo` combo of the repository to get.
* @param {string} [ver] - A version string indicating the version of data we wish to collect.
* @returns {object} A Server Status Object where content is the Markdown text of a readme.
*/
async readme(userObj, ownerRepo) {
async readme(userObj, ownerRepo, ver) {
try {
let reqString = `/repos/${ownerRepo}/readme`;

if (ver) {
reqString += `?ref=${ver}`;
}

const readmeRaw = await this._webRequestAuth(
`/repos/${ownerRepo}/readme`,
reqString,
userObj.token
);
// Using just `/readme` will let GitHub attempt to get the repos prefferred readme file,
Expand Down Expand Up @@ -289,13 +297,20 @@
* @desc Returns the JSON Parsed text of the `package.json` on a GitHub repo.
* @param {object} userObj - The Full User Object as received after verification.
* @param {string} ownerRepo - The String combo of `owner/repo` for the package
* @param {string} [ver] - A version string indicating the version of data we wish to collect.
* @returns {object} A Server Status Object, which when successfully, whose `content`
* Is the JSON parsed `package.json` of the repo specified.
*/
async packageJSON(userObj, ownerRepo) {
async packageJSON(userObj, ownerRepo, ver) {
try {
let reqString = `/repos/${ownerRepo}/contents/package.json`;

if (ver) {
reqString += `?ref=${ver}`;
}

const raw = await this._webRequestAuth(
`/repos/${ownerRepo}/contents/package.json`,
reqString,
userObj.token
);

Expand Down Expand Up @@ -412,10 +427,16 @@
*/
async featureDetection(userObj, ownerRepo) {
// First lets declare the functions we will rely on within this
const providesSnippets = async () => {
const providesSnippets = async (ref) => {
try {
let reqString = `/repos/${ownerRepo}/contents/snippets`;

if (ref) {
reqString += `?ref=${ref}`;
}

const raw = await this._webRequestAuth(
`/repos/${ownerRepo}/contents/snippets`,
reqString,
userObj.token
);

Expand All @@ -435,10 +456,16 @@
}
};

const getGrammars = async () => {
const getGrammars = async (ref) => {
try {
let reqString = `/repos/${ownerRepo}/contents/grammars`;

if (ref) {
reqString += `?ref=${ref}`;
}

const raw = await this._webRequestAuth(
`/repos/${ownerRepo}/contents/grammars`,
ref,
userObj.token
);

Expand All @@ -456,8 +483,14 @@
let supportedLanguages = [];

for (let i = 0; i < raw.content.body.length; i++) {
let innerReqString = `/repos/${ownerRepo}/contents/grammars/${res.body[i].name}`;

if (ref) {
innerReqString += `?ref=${ref}`;
}

const rawInner = this._webRequestAuth(
`/repos/${ownerRepo}/contents/grammars/${res.body[i].name}`,
innerReqString,
userObj.token
);

Expand Down Expand Up @@ -504,8 +537,12 @@

// Now with our utility functions here defined, lets call them and build
// our featureObject
let grammars = await getGrammars();
let snippets = await providesSnippets();
let tags = await tags(userObj, ownerRepo);
Fixed Show fixed Hide fixed
// Sort the tags into descending order
tags.content.sort((a, b) => { return semver.rcompare(a.name, b.name)} );

const grammars = await getGrammars(tags.content[0]?.name);
const snippets = await providesSnippets(tags.content[0]?.name);

let featureObject = {};

Expand Down
11 changes: 11 additions & 0 deletions tests/full/fixtures/d-pulsar-package/initial-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "d-pulsar-package",
"version": "1.0.0",
"description": "A new package for stuff",
"main": "./lib/main.js",
"engines": {
"atom": "*"
},
"repository": "https://github.com/confused-Techie/d-pulsar-package",
"license": "MIT"
}
10 changes: 10 additions & 0 deletions tests/full/fixtures/d-pulsar-package/initial-tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = [
{
name: "v1.0.0",
tarball_url: "https://api.github.com/repos/confused-Techie/d-pulsar-package/tarball/refs/tags/v1.0.0",
commit: {
sha: "09f",
url: "https://api.github.com/repos/confused-Techie/d-pulsar-package/commits/09f"
}
}
];
50 changes: 50 additions & 0 deletions tests/full/fixtures/d-pulsar-package/match.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
module.exports = {
name: "d-pulsar-package",
owner: "confused-Techie",
readme: expect.stringContaining("I'm a readme!"),
metadata: {
main: "./lib/main.js",
name: "d-pulsar-package",
engines: { atom: "*" },
license: "MIT",
version: "2.0.0",
repository: "https://github.com/confused-Techie/d-pulsar-package",
description: "An old package for stuff"
},
releases: { latest: "2.0.0" },
versions: {
"2.0.0": {
dist: {
tarball: expect.stringContaining(
"/api/packages/d-pulsar-package/versions/2.0.0/tarball"
),
},
main: "./lib/main.js",
name: "d-pulsar-package",
license: "MIT",
version: "2.0.0",
repository: "https://github.com/confused-Techie/d-pulsar-package",
description: "An old package for stuff"
},
"1.0.0": {
dist: {
tarball: expect.stringContaining(
"/api/packages/d-pulsar-package/versions/1.0.0/tarball"
),
},
main: "./lib/main.js",
name: "d-pulsar-package",
license: "MIT",
version: "1.0.0",
repository: "https://github.com/confused-Techie/d-pulsar-package",
description: "A new package for stuff"
}
},
repository: {
url: "https://github.com/confused-Techie/d-pulsar-package",
type: "git"
},
downloads: "0",
stargazers_count: "0",
badges: [{ title: "Made for Pulsar!", type: "success" }],
};
11 changes: 11 additions & 0 deletions tests/full/fixtures/d-pulsar-package/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "d-pulsar-package",
"version": "2.0.0",
"description": "An old package for stuff",
"main": "./lib/main.js",
"engines": {
"atom": "*"
},
"repository": "https://github.com/confused-Techie/d-pulsar-package",
"license": "MIT"
}
3 changes: 3 additions & 0 deletions tests/full/fixtures/d-pulsar-package/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# d-pulsar-package

I'm a readme!
Loading
Loading