Skip to content

Commit

Permalink
allow commit hash versioning
Browse files Browse the repository at this point in the history
* add "hashVersionFile" config option
* allow empty version
* Better error messages
* Bump deps
* Reflect changes in readme
  • Loading branch information
Araxeus committed May 29, 2024
1 parent 28b3b69 commit 37b5511
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 48 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ But that's not all - Vendorfiles is not limited to managing text files - it can

- [Installation](#installation)
- [Configuration](#configuration)
- [Versioning Dependencies](#versioning-dependencies)
- [GitHub Releases](#github-releases)
- [Commands](#commands)
- [Sync](#sync)
Expand Down Expand Up @@ -125,6 +126,41 @@ To rename or move files, you can specify an object with the source file as the k
}
```

### Versioning Dependencies

This project uses GitHub releases to determine the version of a dependency. When a new release is made on GitHub, the version of the dependency in this project is updated accordingly, and the files are based on the tag of that release.

However, there is an optional `hashVersionFile` key for each dependency that allows for a different versioning strategy. If `hashVersionFile` is specified, the version is based on the latest commit hash of the file specified by hashVersionFile.

The `hashVersionFile` key can be either:

- A string: In this case, it should be the path to the file in the dependency repository. The version of the dependency will be the latest commit hash of this file.

- A boolean: If `hashVersionFile` is set to true, the path of the first file provided in the file list for that dependency will be used. The version of the dependency will be the latest commit hash of this file.

This versioning strategy allows for more granular control over the version of a dependency, as it can be updated whenever a specific file in the dependency repository changes.

```json
{
"vendorDependencies": {
"Cooltipz": {
"repository": "https://github.com/jackdomleo7/Cooltipz.css",
"version": "f6ec482ea395cead4fd849c05df6edd8da284a52",
"hashVersionFile": "package.json",
"files": ["cooltipz.min.css", "package.json"],
},
"Coloris": {
"repository": "https://github.com/mdbassit/Coloris",
"version": "v0.17.1",
"hashVersionFile": true,
"files": ["dist/coloris.min.js"],
}
}
}
```

> in this example, the version of Cooltipz will be the latest commit hash of the `package.json` file, <br> and the version of Coloris will be the latest commit hash of the `dist/coloris.min.js` file.
### GitHub Releases

You can download release assets by using the `{release}/` placeholder in the file path.
Expand Down
63 changes: 51 additions & 12 deletions lib/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,48 @@ export async function install({
}

if (!newVersion) {
const latestRelease = await github.getLatestRelease(repo);
newVersion = latestRelease.tag_name as string;
if (dependency.hashVersionFile) {
let hashVersionFile = dependency.hashVersionFile;
if (hashVersionFile === true) {
if (typeof dependency.files[0] === 'string') {
hashVersionFile = dependency.files[0];
} else if (typeof dependency.files[0] === 'object') {
hashVersionFile = Object.keys(dependency.files[0])[0];
} else {
error(
`files[0] is invalid for hashVersionFile, must be a string or an object - got ${typeof dependency
.files[0]}`,
);
}
}
if (typeof hashVersionFile === 'string') {
const fileCommitSha = await github
.getFileCommitSha({
repo,
path: hashVersionFile,
})
.catch((err) => {
error(
`Error while getting commit sha for ${hashVersionFile}:\n${err}`,
);
});
newVersion = fileCommitSha;
} else {
error('hashVersionFile is invalid, must be a string or true');
}
} else {
try {
const latestRelease = await github.getLatestRelease(repo);
newVersion = latestRelease.tag_name as string;
} catch {
if (showOutdatedOnly) {
error(`Could not find a version for ${dependency.name}`);
}
newVersion = '';
}
}
}

assert(!!newVersion, `Could not find a version for ${dependency.name}`);

const needUpdate =
force ||
(await checkIfNeedsUpdate({
Expand Down Expand Up @@ -312,7 +348,9 @@ export async function install({
error(
`${err.toString()}:\nCould not download file "${
typeof file === 'string' ? file : file[0]
}" from ${dependency.repository}`,
}" from ${
dependency.repository
} with version ${ref}`,
);
}
});
Expand Down Expand Up @@ -409,8 +447,8 @@ export async function install({
await writeLockfile(
dependency.name,
{
version: newVersion,
repository: dependency.repository,
version: newVersion,
files: dependency.files,
},
lockfilePath,
Expand All @@ -419,12 +457,13 @@ export async function install({
const oldVersion = dependency.version;

if (newVersion !== oldVersion) {
configFile.vendorDependencies[dependency.name] = {
version: newVersion,
repository: dependency.repository,
files: dependency.files,
vendorFolder: dependency.vendorFolder,
} as VendorDependency;
const configDep = configFile.vendorDependencies[dependency.name];
configDep.version = newVersion;
configDep.repository = dependency.repository;
configDep.files = dependency.files;
configDep.vendorFolder = dependency.vendorFolder;
configDep.hashVersionFile = dependency.hashVersionFile;

await writeConfig({
configFile,
configFileSettings,
Expand Down
25 changes: 23 additions & 2 deletions lib/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,35 @@ export async function getLatestRelease({ owner, name: repo }: Repository) {
return res.data;
}

export async function getFileCommitSha({
repo,
path,
}: {
repo: Repository;
path: string;
}) {
const commit = await octokit().repos.listCommits({
owner: repo.owner,
repo: repo.name,
path,
per_page: 1,
});
if (!commit.data?.[0]?.sha) {
error(`No commits found for ${repo.owner}/${repo.name}: ${path}}`);
}
return commit.data[0].sha;
}

export async function getFile({
repo,
path,
ref,
}: {
repo: Repository;
path: string;
ref: string;
ref: string | undefined;
}) {
ref = ref || undefined;
const requestOptions = octokit().repos.getContent.endpoint({
owner: repo.owner,
repo: repo.name,
Expand All @@ -94,7 +114,7 @@ export async function getFile({
const req = await fetch(requestOptions.url, requestOptions);

if (!(req.ok && req.body)) {
throw 'Request failed';
throw `Request failed with status ${req.status}`;
}

return req.body;
Expand Down Expand Up @@ -223,6 +243,7 @@ export async function login(token?: string) {
export default {
login,
getFile,
getFileCommitSha,
getLatestRelease,
downloadReleaseFile,
findRepoUrl,
Expand Down
1 change: 1 addition & 0 deletions lib/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type VendorDependency = {
repository: string;
files: FilesArray;
version?: string;
hashVersionFile?: string | boolean;
name?: string;
vendorFolder?: string;
};
Expand Down
4 changes: 2 additions & 2 deletions lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,16 @@ export function replaceVersion(path: string, version: string) {
export async function writeLockfile(
name: string,
data: {
version: string;
repository: string;
version: string;
files: FilesArray;
},
filepath: string,
): Promise<void> {
let lockfile: Lockfile;
const vendorLock: VendorLock = {
version: data.version,
repository: data.repository,
version: data.version,
files: configFilesToVendorlockFiles(data.files, data.version),
};

Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"publish": "yarn check && yarn npm publish"
},
"dependencies": {
"@commander-js/extra-typings": "^12.0.1",
"@commander-js/extra-typings": "^12.1.0",
"@ltd/j-toml": "^1.38.0",
"@octokit/auth-oauth-device": "^7.1.1",
"@octokit/rest": "^20.1.1",
Expand All @@ -52,17 +52,17 @@
"make-fetch-happen": "^13.0.1",
"open": "^10.1.0",
"parse-json": "^8.1.0",
"unarchive": "^1.1.1",
"unarchive": "^1.1.2",
"yaml": "^2.4.2"
},
"devDependencies": {
"@biomejs/biome": "^1.7.3",
"@types/make-fetch-happen": "^10.0.4",
"@types/node": "^20.12.12",
"@types/node": "^20.12.13",
"@types/parse-json": "^4.0.2",
"cpy-cli": "^5.0.0",
"del-cli": "^5.1.0",
"type-fest": "^4.18.2",
"type-fest": "^4.18.3",
"typescript": "=5.0.4"
},
"vendorDependencies": {
Expand Down
63 changes: 35 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ __metadata:
languageName: node
linkType: hard

"@commander-js/extra-typings@npm:^12.0.1":
version: 12.0.1
resolution: "@commander-js/extra-typings@npm:12.0.1"
"@commander-js/extra-typings@npm:^12.1.0":
version: 12.1.0
resolution: "@commander-js/extra-typings@npm:12.1.0"
peerDependencies:
commander: ~12.0.0
checksum: 10/cd094ec7fa789dd91e20942727f18811b05bdd0006dfeefddbd3054e4ef89592bb20b7a1e93edfa86a77603045c714231a8ae7804ad153775258e74f9f378208
commander: ~12.1.0
checksum: 10/489ef40dcf18508da5d8db288fa1536e294773b8d07e4c1edee6709972fe4310e3713819ef10bdc1d234615c5cf42df6acf9ddce0b31c6c8114be704fd626971
languageName: node
linkType: hard

Expand Down Expand Up @@ -475,12 +475,12 @@ __metadata:
languageName: node
linkType: hard

"@types/node@npm:^20.12.12":
version: 20.12.12
resolution: "@types/node@npm:20.12.12"
"@types/node@npm:^20.12.13":
version: 20.12.13
resolution: "@types/node@npm:20.12.13"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10/e3945da0a3017bdc1f88f15bdfb823f526b2a717bd58d4640082d6eb0bd2794b5c99bfb914b9e9324ec116dce36066990353ed1c777e8a7b0641f772575793c4
checksum: 10/c9f02cfe342bce4aa9221f389115c1f9e3bd9abc87d45e3b2c3a5b92d99523c02b72dd67f50cbbc5edddbaf7dd458cf61dd3289d7a8c14fde80c998df10fee82
languageName: node
linkType: hard

Expand Down Expand Up @@ -800,9 +800,9 @@ __metadata:
languageName: node
linkType: hard

"compressing@npm:^1.8.0":
version: 1.9.0
resolution: "compressing@npm:1.9.0"
"compressing@npm:^1.10.0":
version: 1.10.1
resolution: "compressing@npm:1.10.1"
dependencies:
"@eggjs/yauzl": "npm:^2.11.0"
flushwritable: "npm:^1.0.0"
Expand All @@ -813,7 +813,7 @@ __metadata:
streamifier: "npm:^0.1.1"
tar-stream: "npm:^1.5.2"
yazl: "npm:^2.4.2"
checksum: 10/ddaec9cc1a6a7eef4b3f35fea28ebf6434b88398bcdb492d44fbb2b7a7bb6386a866d13a954df21f23a50f73c81bc561395a71fa1b4ab62ae5fd0a9a3403ec19
checksum: 10/40b716f5abbdda7e8b348f074fbb9b7677c364ca37da4d4c610ec33dcd8478bbc30e59ecb44c4c8ad9b64651c6ed485f9d6e74ce77235bd5e01adff862ee0c77
languageName: node
linkType: hard

Expand Down Expand Up @@ -1137,14 +1137,14 @@ __metadata:
languageName: node
linkType: hard

"file-type@npm:^18.2.1":
version: 18.2.1
resolution: "file-type@npm:18.2.1"
"file-type@npm:^19.0.0":
version: 19.0.0
resolution: "file-type@npm:19.0.0"
dependencies:
readable-web-to-node-stream: "npm:^3.0.2"
strtok3: "npm:^7.0.0"
token-types: "npm:^5.0.1"
checksum: 10/9580707585f9bb026ccf2d5a7dca711e0939e7385aca70e93c316fdb4fe2066356a6ff6bf4b5837effe4a41015ad49544223fde46311d0e72bd151b7fe569a4e
checksum: 10/8befa58f769b19d4a72c214694906b83b584310575300e63c08c48f9f2cfa6cb57fb4e1d08325961938d9dde3ecc4f5737b1604ddedfd759f5a1e65e5b0ca577
languageName: node
linkType: hard

Expand Down Expand Up @@ -2554,7 +2554,14 @@ __metadata:
languageName: node
linkType: hard

"type-fest@npm:^4.18.2, type-fest@npm:^4.7.1":
"type-fest@npm:^4.18.3":
version: 4.18.3
resolution: "type-fest@npm:4.18.3"
checksum: 10/eb750920d0ef3639177f581edd6489d972c5c5827abb602a9c9662889aad148a7d558257e36c563f1beb81a2e417faec52ecec9799b28531d8335856f91e6dff
languageName: node
linkType: hard

"type-fest@npm:^4.7.1":
version: 4.18.2
resolution: "type-fest@npm:4.18.2"
checksum: 10/2c176de28384a247fac1503165774e874c15ac39434a775f32ecda3aef5a0cefcfa2f5fb670c3da1f81cf773c355999154078c8d9657db19b65de78334b27933
Expand All @@ -2581,13 +2588,13 @@ __metadata:
languageName: node
linkType: hard

"unarchive@npm:^1.1.1":
version: 1.1.1
resolution: "unarchive@npm:1.1.1"
"unarchive@npm:^1.1.2":
version: 1.1.2
resolution: "unarchive@npm:1.1.2"
dependencies:
compressing: "npm:^1.8.0"
file-type: "npm:^18.2.1"
checksum: 10/268063bb5535e35242f48a1a838a9020302be52de21e44797063025381f55a1fb194328dc1ff75d01133ace8bc6146ac5111bc1efe24908ef717f132d18e7881
compressing: "npm:^1.10.0"
file-type: "npm:^19.0.0"
checksum: 10/71e03c741a7d0f4c9a75086335f22c8da45f7a661eb9dee829f18b12801cf7ae59bdd79b3fa99973431b58e4e248bee057cf9a503c1ff70b4801ead9b4a4728a
languageName: node
linkType: hard

Expand Down Expand Up @@ -2652,12 +2659,12 @@ __metadata:
resolution: "vendorfiles@workspace:."
dependencies:
"@biomejs/biome": "npm:^1.7.3"
"@commander-js/extra-typings": "npm:^12.0.1"
"@commander-js/extra-typings": "npm:^12.1.0"
"@ltd/j-toml": "npm:^1.38.0"
"@octokit/auth-oauth-device": "npm:^7.1.1"
"@octokit/rest": "npm:^20.1.1"
"@types/make-fetch-happen": "npm:^10.0.4"
"@types/node": "npm:^20.12.12"
"@types/node": "npm:^20.12.13"
"@types/parse-json": "npm:^4.0.2"
commander: "npm:^12.1.0"
cpy-cli: "npm:^5.0.0"
Expand All @@ -2668,9 +2675,9 @@ __metadata:
make-fetch-happen: "npm:^13.0.1"
open: "npm:^10.1.0"
parse-json: "npm:^8.1.0"
type-fest: "npm:^4.18.2"
type-fest: "npm:^4.18.3"
typescript: "npm:=5.0.4"
unarchive: "npm:^1.1.1"
unarchive: "npm:^1.1.2"
yaml: "npm:^2.4.2"
bin:
vendor: ./dist/cli.js
Expand Down

0 comments on commit 37b5511

Please sign in to comment.