Compare commits

..

No commits in common. "main" and "test" have entirely different histories.
main ... test

6 changed files with 136 additions and 366 deletions

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
node_modules
.vscode-test/
*.vsix
.vscode/bookmarks.json

View file

@ -1,71 +1,9 @@
# Change Log
## [Unreleased] <sub><sup><sub>_(not ordered)_</sub></sup></sub>
All notable changes to the "dwm-git-simpleuse" extension will be documented in this file.
- Task API
- Upload only active file
- Make it possible to receive a webhook to send info to user => maybe not possible
- clean code (more)
- check if commit msg was already pushed with `git log main --format=%s` and propose increment
- make a better Readme.md
- rename extension
- better logo ?
- description in package.json
- if possible verify credential manager
- if possible, Show a list of available repositories
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
## [0.3.1] - 2024-07-19
## [Unreleased]
- fix initRepo command
## [0.3.0] - 2024-07-19
- fix autoIncrement > if 2x same number, it incremented the wrong one
- check for conflicts before push
- clickable link to file
- keep lastGitCommitMsg through vscode restart
- trim commit message before push
- clean code
- check if in git repository before running commands => better
- "fix" "Merge branch 'main' of https://[...]" in commit message => `git pull --rebase`
- fix/improve error output
- change `git pull --ff` to `git pull --rebase --autostash` to make it possible to pull when there are uncommited changes
## [0.2.0] - 2024-07-19
- No git msgs as errors
- Added status bar item (show loading/error)
- Log now goes to an outputLogChannel
- check if in git repository before running commands
- can "disable" extention if not in git repository
## [0.1.3] - 2024-07-18
- Fixed "commit message auto increment"
- Fixed commit message couldn't have `'` in it
- added `--ff` to git pull
## [0.1.2] - 2024-07-11
- Fixed "initialize existing repository" command
- Renamed commands with "gitDWM : " prefix
## [0.1.0] - 2024-04-10
- Choose commmit message
- Commit message auto increment
- Command to initialize existing repository
- Activation event set to "onStartupFinished"
## [0.0.2] - 2024-02-02
- Renamed command to something else than "helloworld" => ("full push")
## [0.0.1] - 2024-02-01
- Initial release
## [removed from plan]
- message on quit (vscode) if not everything is pushed => doesn't seem possible with vsocde api
- status bar item onClick doesn't realy check if outputLogChannel is opened => not possible to fix because of vscode API
- Initial release

View file

@ -1,3 +1,3 @@
This extention is in beta, some errors may occur,
errors given through vscode notifications can be ignored for most of them,
it needs to and will improve over time.
This extention is in beta, some errors may occur,
errors given through vscode notifications can be ignored for most of them,
it needs and will improve over time.

View file

@ -1,248 +1,98 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
const vscode = require("vscode");
const util = require("node:util");
const chp = require("child_process");
const execP = util.promisify(chp.exec);
let isOutPutChannelVisible = false,
logOutputChannel,
statusBarItem;
// This method is called when your extension is activated
// Your extension is activated the very first time the command is executed
/**
* @param {vscode.ExtensionContext} context
*/
async function activate(context) {
let disposable;
function activate(context) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log("yo!");
logOutputChannel = makeLogOutputChannel("gitDWMSimpleUse");
statusBarItem = makeStatusBarItem();
context.subscriptions.push(
vscode.commands.registerCommand("gitDWMSimpleUse.ToggleOutputChannel", () => {
if (isOutPutChannelVisible) logOutputChannel.hide();
else logOutputChannel.show(true);
isOutPutChannelVisible = !isOutPutChannelVisible;
})
);
try {
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
} catch (err) {
vscode.window.showErrorMessage(err);
}
chp.execFile("git", ["pull"], (err, stdout, stderr) => {
if (err) {
vscode.window.showErrorMessage("GITPULL : " + err.message);
return;
}
if (stderr) {
vscode.window.showErrorMessage("GITPULL : " + stderr);
return;
}
vscode.window.showInformationMessage("GITPULL : " + stdout);
});
try {
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
} catch (err) {
vscode.window.showErrorMessage(err);
}
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand(
"dwm-git-simpleuse.helloWorld",
function () {
chp.exec(
"git add . && git commit -am 'test77' && git pull && git push",
{ cwd: vscode.workspace.workspaceFolders[0].uri.fsPath },
(err, stdout, stderr) => {
if (err) {
vscode.window.showErrorMessage(err.message);
return;
}
if (stderr) {
vscode.window.showErrorMessage(stderr);
return;
}
vscode.window.showInformationMessage(stdout);
}
);
/* try {
process.chdir(vscode.workspace.workspaceFolders[0].uri.fsPath);
} catch (err) {
vscode.window.showErrorMessage(err);
} */
/* chp.execFile("git", ["add", "*"], (err, stdout, stderr) => {
if (err) {
vscode.window.showErrorMessage("GITADD : " + err.message);
return;
}
if (stderr) {
vscode.window.showErrorMessage("GITADD : " + stderr);
return;
}
vscode.window.showInformationMessage("GITADD : " + stdout);
});
chp.execFile(
"git",
["commit", "-m test7", "-a"],
(err, stdout, stderr) => {
if (err) {
vscode.window.showErrorMessage("GITCOM : " + err.message);
return;
}
if (stderr) {
vscode.window.showErrorMessage("GITCOM : " + stderr);
return;
}
vscode.window.showInformationMessage("GITCOM : " + stdout);
}
); */
}
);
if (await isInGitRepo()) {
statusBarItem.show();
if (!(await hasConflicts(true)))
makeSpawn("openPull", "git pull --rebase --autostash", { shell: true });
}
context.subscriptions.push(makeDocumentLinkProvider());
disposable = vscode.commands.registerCommand("dwm-git-simpleuse.fullPush", async function () {
if (
!(await isInGitRepo(true)) ||
(await hasConflicts(true)) ||
(await isWorkingTreeClean(true))
)
return;
let commitMsg = await vscode.window.showInputBox({
placeHolder: "commit message",
prompt: "choose your commit message",
value: ((await context.workspaceState.get("lastGitCommitMsg")) || "").incrementSuffixe(),
});
if (commitMsg === undefined) return;
commitMsg = commitMsg.trim();
if (!commitMsg.length) {
vscode.window.showErrorMessage("commit message needed");
return;
}
context.workspaceState.update("lastGitCommitMsg", commitMsg);
await makeSpawn("fullPush-pull", `git pull --rebase --autostash`, { shell: true });
if (await hasConflicts(true)) return;
makeSpawn(
"fullPush",
`git add . && git commit -am "${commitMsg.replace(/"/g, '\\"')}" && git push`,
{ shell: true }
);
});
context.subscriptions.push(disposable);
disposable = vscode.commands.registerCommand("dwm-git-simpleuse.initRepo", async function () {
if (await isInGitRepo()) {
vscode.window.showErrorMessage("Already in a git repository");
return;
}
let gitLink = await vscode.window.showInputBox({
placeHolder: "git repo link",
prompt: "Initialize a git repository",
value: await vscode.env.clipboard.readText(),
});
if (gitLink === undefined) return;
gitLink = gitLink.trim();
if (!gitLink.match(/^https?:\/\/\S+\.git$/).length) {
vscode.window.showErrorMessage("Link not valid");
return;
}
let gitBranch = await vscode.window.showInputBox({
placeHolder: "git branch",
prompt: "choose wich branch to use (defaults to 'main')",
value: "main",
});
if (gitBranch === undefined) return;
gitBranch = gitBranch.trim();
if (!gitBranch.length) gitBranch = "main";
makeSpawn(
"initRepo",
`git init && git remote add origin ${gitLink} && git fetch && git checkout -ft origin/${gitBranch}`,
{ shell: true }
);
});
context.subscriptions.push(disposable);
context.subscriptions.push(disposable);
}
// This method is called when your extension is deactivated
function deactivate() {}
module.exports = {
activate,
deactivate,
activate,
deactivate,
};
function makeSpawn(name, command, options = {}) {
return new Promise((resolve) => {
statusBarItem.text = "$(loading~spin) GitDWMSU";
statusBarItem.tooltip = name;
let spawn = chp.spawn(`${command} 2>&1 || echo 'gitSU_error'`, options);
spawn.stdout.on("data", (d) => {
if (/\n\s*gitSU_error[\s\n]*$/.test(d.toString())) {
statusBarItem.backgroundColor = new vscode.ThemeColor("statusBarItem.errorBackground");
setTimeout(() => {
statusBarItem.backgroundColor = new vscode.ThemeColor("statusBarItem.background");
}, 5000);
vscode.window.showErrorMessage(`[${name}] An error occurred`, "Show").then((e) => {
if (e == "Show") {
logOutputChannel.show(true);
isOutPutChannelVisible = true;
}
});
logOutputChannel.error(`[${name}] ${d.toString().replace(/\n\s*gitSU_error[\s]*/, "")}`);
} else logOutputChannel.info(`[${name}] ${d.toString()}`);
});
spawn.stderr.on("data", (d) => {
logOutputChannel.error(`[${name}] ${d.toString()}`);
});
spawn.on("close", (c) => {
logOutputChannel.trace(`[${name}] child process exited with code ${c}`);
statusBarItem.text = "$(remote) GitDWMSU";
statusBarItem.tooltip = "";
resolve();
});
});
}
async function isWorkingTreeClean(doActions = false) {
const { stdout } = await execP(`git status --porcelain`);
if (doActions && stdout.trim() == "") vscode.window.showErrorMessage(`Working tree is clean`);
return stdout.trim() == "";
}
async function isInGitRepo(doActions = false) {
const { stdout } = await execP(`git rev-parse --is-inside-work-tree || echo false`);
if (doActions && stdout.trim() !== "true") vscode.window.showErrorMessage("Not a git repository");
return stdout.trim() === "true";
}
async function hasConflicts(doActions = false) {
const { stdout } = await execP(`git diff --name-only --diff-filter=U`);
if (doActions && stdout.trim() != "") {
vscode.window
.showErrorMessage(
`You have to resolve conflicts :\n${stdout.trim().replace("\n", ", ")}`,
"Show files",
"Git pull"
)
.then(async (e) => {
if (e == "Show files") {
logOutputChannel.show(true);
isOutPutChannelVisible = true;
} else if (e == "Git pull" && !(await hasConflicts(true))) {
makeSpawn("openPull", "git pull --rebase --autostash", { shell: true });
}
});
logOutputChannel.error(
"[conflicts] Conflicted files : \n" +
stdout
.split("\n")
.filter((e) => e.trim().length)
.map((e) => `F:${e}#`)
.join("\n")
);
}
return stdout.trim() != "";
}
String.prototype.incrementSuffixe = function () {
const match = this.match(/\s*\((\d+)\)\s*$/);
return match
? this.replace(new RegExp(`${match[0].escapeRegex()}$`), ` (${+match[1] + 1})`)
: this.trim().length
? this + " (1)"
: this.trim();
};
String.prototype.escapeRegex = function () {
return this.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&");
};
function makeLogOutputChannel(name) {
return vscode.window.createOutputChannel(name, {
log: true,
logLevel: 3,
});
}
function makeStatusBarItem() {
let s = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
s.text = "$(remote) GitDWMSU";
s.command = "gitDWMSimpleUse.ToggleOutputChannel";
return s;
}
function makeDocumentLinkProvider() {
return vscode.languages.registerDocumentLinkProvider(
{ language: "log", scheme: "output" },
{
provideDocumentLinks(doc) {
const links = [];
const regex = /F(ile|older)?:([^#]+)#/g;
for (let line = 0; line < doc.lineCount; line++) {
let text = doc.lineAt(line).text;
let match;
while ((match = regex.exec(text)) !== null) {
const _index = match.index + 2 + (match[1] ? match[1].length : 0);
const range = new vscode.Range(
new vscode.Position(line, _index),
new vscode.Position(line, _index + match[2].length)
);
links.push(
new vscode.DocumentLink(
range,
vscode.Uri.file(
(match[1] ? "" : `${vscode.workspace.workspaceFolders[0].uri.fsPath}/`) + match[2]
)
)
);
}
}
return links;
},
}
);
}

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "dwm-git-simpleuse",
"version": "0.3.1",
"version": "0.0.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "dwm-git-simpleuse",
"version": "0.3.1",
"version": "0.0.1",
"dependencies": {
"child_process": "^1.0.2"
},

View file

@ -1,65 +1,48 @@
{
"name": "dwm-git-simpleuse",
"displayName": "DWM_git_simpleUse",
"icon": "img/icon.png",
"description": "",
"publisher": "nyncral",
"version": "0.3.1",
"engines": {
"vscode": "^1.85.0"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"main": "./extension.js",
"contributes": {
"commands": [
{
"command": "dwm-git-simpleuse.fullPush",
"title": "gitDWM : full push"
},
{
"command": "dwm-git-simpleuse.initRepo",
"title": "gitDWM : initialize existing repository"
}
],
"keybindings": [
{
"command": "dwm-git-simpleuse.fullPush",
"key": "ctrl+alt+s"
}
],
"configuration": {
"type": "object",
"title": "DWM Git Simple Use Configuration",
"properties": {
"dwm-git-simpleuse.isEnabled": {
"type": "boolean",
"default": true,
"description": "Enable DWM Git Simple Use extension",
"scope": "resource"
}
}
}
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "vscode-test"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
"@types/vscode": "^1.85.0",
"@vscode/test-cli": "^0.0.4",
"@vscode/test-electron": "^2.3.8",
"eslint": "^8.56.0",
"typescript": "^5.3.3"
},
"dependencies": {
"child_process": "^1.0.2"
}
"name": "dwm-git-simpleuse",
"displayName": "DWM_git_simpleUse",
"icon": "img/icon.png",
"description": "",
"publisher": "nyncral",
"version": "0.0.1",
"engines": {
"vscode": "^1.85.0"
},
"categories": [
"Other"
],
"activationEvents": [],
"main": "./extension.js",
"contributes": {
"commands": [
{
"command": "dwm-git-simpleuse.helloWorld",
"title": "HelloWorld23"
}
],
"keybindings": [
{
"command": "dwm-git-simpleuse.helloWorld",
"key": "ctrl+alt+r",
"mac": "cmd+alt+r"
}
]
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "vscode-test"
},
"devDependencies": {
"@types/mocha": "^10.0.6",
"@types/node": "18.x",
"@types/vscode": "^1.85.0",
"@vscode/test-cli": "^0.0.4",
"@vscode/test-electron": "^2.3.8",
"eslint": "^8.56.0",
"typescript": "^5.3.3"
},
"dependencies": {
"child_process": "^1.0.2"
}
}