Compare commits
46 commits
Author | SHA1 | Date | |
---|---|---|---|
d58ee184f6 |
|||
e38c1e283a |
|||
527a0db975 |
|||
5b22b39bcf |
|||
1ddf033a1b |
|||
a85bf10d8b |
|||
820140c176 |
|||
78f190c26e |
|||
a2658c0a7c |
|||
faea07302a |
|||
0b72bf61db |
|||
525bebd78f |
|||
142c665aac |
|||
e2939326c6 |
|||
12c6d3f841 |
|||
37b8a37d5f |
|||
ecd055d3eb |
|||
7038897594 |
|||
c44822ffa3 | |||
3f6eab94c1 |
|||
de3f5e697c |
|||
703db757bc |
|||
50ecd8ce86 |
|||
618e00b677 |
|||
|
deb4eabbce | ||
1f0d3aa030 |
|||
|
f8f7ede4b9 | ||
a38aedc248 |
|||
|
e77e7fbac8 | ||
6a1b731730 |
|||
|
18a7d4e156 | ||
69fa25bc1d |
|||
81ee09b42f |
|||
|
93fc34ac15 | ||
f238c9aae9 |
|||
8bfcadd11f |
|||
|
9c9121500b | ||
8212b10e25 |
|||
|
0ec25d1693 | ||
fb23f6fd8b |
|||
|
85f3baef47 | ||
1f3158fd53 |
|||
|
630fab7ce6 | ||
9c16070b54 |
|||
7dc849688f |
|||
9284088629 |
11 changed files with 9832 additions and 28 deletions
19
.gitea/size.yml
Normal file
19
.gitea/size.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
buckets:
|
||||||
|
- maxSize: 80
|
||||||
|
label: size/small
|
||||||
|
comment: null
|
||||||
|
- maxSize: 200
|
||||||
|
label: size/medium
|
||||||
|
comment: null
|
||||||
|
- maxSize: 2000
|
||||||
|
label: size/large
|
||||||
|
comment: >
|
||||||
|
👮♀️⚠️ This is a friendly reminder that the diff size of this PR is bigger than
|
||||||
|
200 lines we aim for. Please consider splitting this PR into more digestible pieces!
|
||||||
|
- maxSize: Infinity
|
||||||
|
label: size/huge
|
||||||
|
comment: >
|
||||||
|
👮♀️🛑 This PR's diff size is quite huge.
|
||||||
|
Hopefully you know what you're doing.
|
||||||
|
If you did not commit a lot of autogenerated files intentionally,
|
||||||
|
there are few good reasons for this.
|
31
.gitea/workflows/release.yml
Normal file
31
.gitea/workflows/release.yml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
name: Release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "release"
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Release
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
- uses: oven-sh/setup-bun@v2
|
||||||
|
with:
|
||||||
|
bun-version: latest
|
||||||
|
- name: Create Release
|
||||||
|
uses: https://git.kjan.de/actions/semantic-release@v1.1.0
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
17
.gitea/workflows/size.yml
Normal file
17
.gitea/workflows/size.yml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: Label PRs based on size
|
||||||
|
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
add_pr_size_label:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Check PR size
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Label and comment PR
|
||||||
|
uses: boschresearch/pr-size-labeler@v5.0.2
|
||||||
|
with:
|
||||||
|
bucketConfigFile: ".gitea/size.yml"
|
57
CHANGELOG.md
Normal file
57
CHANGELOG.md
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
## [0.3.3](https://git.kjan.de/jank/project-cli/compare/v0.3.2...v0.3.3) (2025-06-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix wrong config ([1f0d3aa](https://git.kjan.de/jank/project-cli/commit/1f0d3aa030d462b7f1df1646b7b4431a8ef43d2c))
|
||||||
|
|
||||||
|
## [0.3.2](https://git.kjan.de/jank/project-cli/compare/v0.3.1...v0.3.2) (2025-06-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Remove stupid toml ([a38aedc](https://git.kjan.de/jank/project-cli/commit/a38aedc2481930a9bc5ac4454e5b0b4b6fff5104))
|
||||||
|
|
||||||
|
## [0.3.1](https://git.kjan.de/jank/project-cli/compare/v0.3.0...v0.3.1) (2025-06-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Setup bun ([6a1b731](https://git.kjan.de/jank/project-cli/commit/6a1b7317308fdeb2719c258f6c2b62463d81ca3a))
|
||||||
|
|
||||||
|
## [0.3.0](https://git.kjan.de/jank/project-cli/compare/v0.2.2...v0.3.0) (2025-06-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add some compiling ([81ee09b](https://git.kjan.de/jank/project-cli/commit/81ee09b42fafa5300e384a236602ee22f838da00))
|
||||||
|
|
||||||
|
## [0.2.2](https://git.kjan.de/jank/project-cli/compare/v0.2.1...v0.2.2) (2025-06-19)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Fix releases ([8bfcadd](https://git.kjan.de/jank/project-cli/commit/8bfcadd11f346645eb79027349b791d016ca2b0d))
|
||||||
|
|
||||||
|
## [0.2.1](https://git.kjan.de/jank/project-cli/compare/v0.2.0...v0.2.1) (2025-06-19)
|
||||||
|
|
||||||
|
### Chores
|
||||||
|
|
||||||
|
* Add size pipeline ([8212b10](https://git.kjan.de/jank/project-cli/commit/8212b10e2572e2e6e34775858391dc1fadb9686c))
|
||||||
|
|
||||||
|
## [0.2.0](https://git.kjan.de/jank/project-cli/compare/v0.1.1...v0.2.0) (2025-06-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add basic project creation ([fb23f6f](https://git.kjan.de/jank/project-cli/commit/fb23f6fd8b5c4f625524a86e2378aa2b503458a8))
|
||||||
|
|
||||||
|
## [0.1.1](https://git.kjan.de/jank/project-cli/compare/v0.1.0...v0.1.1) (2025-06-19)
|
||||||
|
|
||||||
|
### Chores
|
||||||
|
|
||||||
|
* **deps:** add renovate.json ([9284088](https://git.kjan.de/jank/project-cli/commit/92840886290ed4796d16643f49b5c4d622814e55))
|
||||||
|
|
||||||
|
## [0.1.0](https://git.kjan.de/jank/project-cli/compare/v0.0.1...v0.1.0) (2025-06-19)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add releases ([7dc8496](https://git.kjan.de/jank/project-cli/commit/7dc849688fa9189e360c5fb491b2e8cd630a57d1))
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Use newer version of the release action ([9c16070](https://git.kjan.de/jank/project-cli/commit/9c16070b54a634b78fffd341ac5b0190ae2fedbb))
|
|
@ -1,11 +1,38 @@
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import os from "os";
|
import os from "os";
|
||||||
import * as toml from "@std/toml";
|
|
||||||
|
|
||||||
export const configPath = os.homedir() + "/.config/project-cli/";
|
export const configPath = os.homedir() + "/.config/project-cli/";
|
||||||
|
|
||||||
|
export interface Project {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Configuration {
|
export interface Configuration {
|
||||||
projectsDirectory: string;
|
projectsDirectory: string;
|
||||||
|
cloningCommand: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getProjects(): Project[] {
|
||||||
|
const projectsString = fs
|
||||||
|
.readFileSync(configPath + "projects.json")
|
||||||
|
.toString();
|
||||||
|
return JSON.parse(projectsString) as Project[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getConfiguration(): Configuration {
|
||||||
|
return JSON.parse(
|
||||||
|
fs.readFileSync(configPath + "config.json").toString(),
|
||||||
|
) as Configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addProject(project: Project) {
|
||||||
|
let projects = getProjects();
|
||||||
|
if (projects.length == undefined) {
|
||||||
|
saveProjects([project]);
|
||||||
|
} else {
|
||||||
|
projects.push(project);
|
||||||
|
saveProjects(projects);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateDefaultConfig() {
|
export function generateDefaultConfig() {
|
||||||
|
@ -14,10 +41,17 @@ export function generateDefaultConfig() {
|
||||||
|
|
||||||
const defaultConfig: Configuration = {
|
const defaultConfig: Configuration = {
|
||||||
projectsDirectory: os.homedir() + "/projects",
|
projectsDirectory: os.homedir() + "/projects",
|
||||||
|
cloningCommand: "git clone %s %n",
|
||||||
};
|
};
|
||||||
|
|
||||||
const configString = toml.stringify(
|
const configString = JSON.stringify(defaultConfig);
|
||||||
defaultConfig as unknown as Record<string, unknown>,
|
fs.writeFileSync(configPath + "config.json", configString);
|
||||||
);
|
|
||||||
fs.writeFileSync(configPath + "config.toml", configString);
|
const projects: Project[] = [];
|
||||||
|
saveProjects(projects);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveProjects(projects: Project[]) {
|
||||||
|
const projectsString = JSON.stringify(projects);
|
||||||
|
fs.writeFileSync(configPath + "projects.json", projectsString);
|
||||||
}
|
}
|
||||||
|
|
122
index.ts
122
index.ts
|
@ -1,23 +1,119 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import { confirm } from "@inquirer/prompts";
|
import { confirm, select, input } from "@inquirer/prompts";
|
||||||
import { exit } from "process";
|
import { exit } from "process";
|
||||||
import {
|
import {
|
||||||
|
addProject,
|
||||||
configPath,
|
configPath,
|
||||||
generateDefaultConfig,
|
generateDefaultConfig,
|
||||||
|
getConfiguration,
|
||||||
|
getProjects,
|
||||||
|
type Project,
|
||||||
} from "./configuration/configuration";
|
} from "./configuration/configuration";
|
||||||
|
import { execSync } from "child_process";
|
||||||
|
import { program } from "commander";
|
||||||
|
|
||||||
if (!fs.existsSync(configPath + "config.toml")) {
|
import packageJson from "./package.json";
|
||||||
const createConfig = await confirm({
|
export const VERSION = packageJson.version;
|
||||||
message: "No cofig has been found. Would you like to generate a new one?",
|
|
||||||
|
const CLI_NAME = "pcli";
|
||||||
|
|
||||||
|
program
|
||||||
|
.name("project-cli")
|
||||||
|
.description("A cli for managing projects")
|
||||||
|
.version(VERSION)
|
||||||
|
.action(async () => {
|
||||||
|
if (!fs.existsSync(configPath + "config.json")) {
|
||||||
|
const createConfig = await confirm({
|
||||||
|
message:
|
||||||
|
"No cofig has been found. Would you like to generate a new one?",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (createConfig) {
|
||||||
|
generateDefaultConfig();
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
"This project can not run without the config. Either create it yourself or generate the default.",
|
||||||
|
);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!getProjects() ||
|
||||||
|
getProjects().length == 0 ||
|
||||||
|
getProjects().length == undefined
|
||||||
|
) {
|
||||||
|
const anwser = await select({
|
||||||
|
message: "Create a new Project",
|
||||||
|
choices: ["Clone a project with git", "Create a new empty Project"],
|
||||||
|
});
|
||||||
|
if (anwser == "Clone a project with git") {
|
||||||
|
const repoUrl = await input({
|
||||||
|
message: "What is the url of the repo?",
|
||||||
|
});
|
||||||
|
const wantsCustomName = await confirm({
|
||||||
|
message: "Would you like to give this project a custom name?",
|
||||||
|
default: false,
|
||||||
|
});
|
||||||
|
let customName = "";
|
||||||
|
if (wantsCustomName) {
|
||||||
|
customName = await input({
|
||||||
|
message: "What would you like the custom name to be?",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
execSync(
|
||||||
|
"cd " +
|
||||||
|
getConfiguration().projectsDirectory +
|
||||||
|
" && " +
|
||||||
|
getConfiguration()
|
||||||
|
.cloningCommand.replace("%s", repoUrl)
|
||||||
|
.replace("%n", customName),
|
||||||
|
);
|
||||||
|
|
||||||
|
const newProject: Project = {
|
||||||
|
name: customName,
|
||||||
|
};
|
||||||
|
addProject(newProject);
|
||||||
|
} else if (anwser == "Create a new empty Project") {
|
||||||
|
const name = await input({
|
||||||
|
message: "What would you like to call the project?",
|
||||||
|
});
|
||||||
|
fs.mkdirSync(getConfiguration().projectsDirectory + "/" + name);
|
||||||
|
const newProject: Project = {
|
||||||
|
name: name,
|
||||||
|
};
|
||||||
|
addProject(newProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const pickedProject = await select({
|
||||||
|
message: "Which Project would you like to go to?",
|
||||||
|
choices: getProjects().map((project: Project) => project.name),
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"__EXEC__ cd " +
|
||||||
|
getConfiguration().projectsDirectory +
|
||||||
|
"/" +
|
||||||
|
pickedProject,
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(getProjects());
|
||||||
});
|
});
|
||||||
|
|
||||||
if (createConfig) {
|
program.command("init").action(() => {
|
||||||
generateDefaultConfig();
|
console.log(`${CLI_NAME}() {
|
||||||
} else {
|
command ${CLI_NAME} "$@" | while IFS= read -r line; do
|
||||||
console.log(
|
if [[ $line == __EXEC__* ]]; then
|
||||||
"This project can not run without the config. Either create it yourself or generate the default.",
|
eval "\${line#__EXEC__}"
|
||||||
);
|
else
|
||||||
exit(1);
|
echo "$line"
|
||||||
}
|
fi
|
||||||
}
|
done
|
||||||
|
}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
program.parse();
|
||||||
|
|
8208
package-lock.json
generated
Normal file
8208
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
26
package.json
26
package.json
|
@ -1,7 +1,19 @@
|
||||||
{
|
{
|
||||||
"name": "project-cli",
|
"name": "proj-cli",
|
||||||
|
"version": "0.3.3",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"bin": {
|
||||||
|
"pcli": "./dist/index.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "bun build index.ts --outfile dist/index.js --target node",
|
||||||
|
"dev": "bun run index.ts",
|
||||||
|
"prepublishOnly": "bun run build"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/"
|
||||||
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
},
|
},
|
||||||
|
@ -9,10 +21,16 @@
|
||||||
"typescript": "^5.0.0"
|
"typescript": "^5.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@std/toml": "npm:@jsr/std__toml",
|
"@saithodev/semantic-release-gitea": "^2.1.0",
|
||||||
|
"@semantic-release/changelog": "^6.0.3",
|
||||||
|
"@semantic-release/git": "^10.0.1",
|
||||||
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
||||||
"@types/commander": "^2.12.5",
|
"@types/commander": "^2.12.5",
|
||||||
"@types/inquirer": "^9.0.8",
|
"@types/inquirer": "^9.0.8",
|
||||||
"commander": "^14.0.0",
|
"commander": "^14.0.0",
|
||||||
"inquirer": "^12.6.3"
|
"commitlint-plugin-cleanfeet": "^0.1.2",
|
||||||
|
"conventional-changelog-conventionalcommits": "^9.0.0",
|
||||||
|
"inquirer": "^12.6.3",
|
||||||
|
"semantic-release": "^24.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
66
release.config.cjs
Normal file
66
release.config.cjs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
module.exports = {
|
||||||
|
branches: ["release"],
|
||||||
|
plugins: [
|
||||||
|
[
|
||||||
|
"@semantic-release/commit-analyzer",
|
||||||
|
{
|
||||||
|
preset: "angular",
|
||||||
|
releaseRules: [
|
||||||
|
{ type: "feat", release: "minor" },
|
||||||
|
{ type: "fix", release: "patch" },
|
||||||
|
{ type: "perf", release: "patch" },
|
||||||
|
{ type: "docs", release: "patch" },
|
||||||
|
{ type: "style", release: "patch" },
|
||||||
|
{ type: "refactor", release: "patch" },
|
||||||
|
{ type: "test", release: "patch" },
|
||||||
|
{ type: "chore", release: "patch" },
|
||||||
|
{ type: "ci", release: "patch" },
|
||||||
|
{ type: "build", release: "patch" },
|
||||||
|
{ type: "revert", release: "patch" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@semantic-release/release-notes-generator",
|
||||||
|
{
|
||||||
|
preset: "conventionalcommits",
|
||||||
|
presetConfig: {
|
||||||
|
types: [
|
||||||
|
{ type: "feat", section: "Features", hidden: false },
|
||||||
|
{ type: "fix", section: "Bug Fixes", hidden: false },
|
||||||
|
{
|
||||||
|
type: "perf",
|
||||||
|
section: "Performance Improvements",
|
||||||
|
hidden: false,
|
||||||
|
},
|
||||||
|
{ type: "docs", section: "Documentation", hidden: false },
|
||||||
|
{ type: "style", section: "Code Style", hidden: false },
|
||||||
|
{ type: "refactor", section: "Code Refactoring", hidden: false },
|
||||||
|
{ type: "test", section: "Tests", hidden: false },
|
||||||
|
{ type: "chore", section: "Chores", hidden: false },
|
||||||
|
{ type: "ci", section: "Continuous Integration", hidden: false },
|
||||||
|
{ type: "build", section: "Build System", hidden: false },
|
||||||
|
{ type: "revert", section: "Reverts", hidden: false },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
parserOpts: {
|
||||||
|
noteKeywords: ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@semantic-release/changelog",
|
||||||
|
{
|
||||||
|
changelogFile: "CHANGELOG.md",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"@saithodev/semantic-release-gitea",
|
||||||
|
{
|
||||||
|
giteaUrl: "https://git.kjan.de",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"@semantic-release/npm",
|
||||||
|
"@semantic-release/git",
|
||||||
|
],
|
||||||
|
};
|
6
renovate.json
Normal file
6
renovate.json
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"local>Renovate/renovate-config"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue