-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpullFromGithub.qml
More file actions
158 lines (138 loc) · 7.04 KB
/
Copy pathpullFromGithub.qml
File metadata and controls
158 lines (138 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//==============================================
// Pull from GitHub
// Pulls latest changes for the Scores repo.
// If pull can't merge cleanly, extracts remote copy for MuseScore Diff.
//==============================================
import QtQuick 2.0
import MuseScore 3.0
import Muse.UiComponents 1.0
import FileIO 3.0
MuseScore {
id: pullPlugin
title: "Pull from GitHub"
categoryCode: "composing-arranging-tools"
menuPath: "Plugins.Pull from GitHub"
description: "Pull latest score from GitHub (diff if needed)"
version: "1.0"
requiresScore: true
FileIO { id: fileIO }
MessageDialog {
id: msg
title: "Pull from GitHub"
visible: false
onAccepted: quit()
}
onRun: {
if (typeof curScore == 'undefined' || curScore == null) { quit(); return; }
var scoreName = curScore.scoreName;
// ---- resolve paths ----
var pluginDirUrl = Qt.resolvedUrl(".");
var pluginDirStr = (pluginDirUrl.toString
? pluginDirUrl.toString()
: ("" + pluginDirUrl)).replace("file:///", "").replace(/\/$/, "");
var lastSlash = Math.max(pluginDirStr.lastIndexOf("/"), pluginDirStr.lastIndexOf("\\"));
var pluginDir = lastSlash > 0 ? pluginDirStr.substring(0, lastSlash) : pluginDirStr;
if (pluginDir.indexOf("Plugins") === -1) pluginDir = pluginDirStr;
var ms4Dir = pluginDir.substring(0, Math.max(pluginDir.lastIndexOf("/"), pluginDir.lastIndexOf("\\")));
var scoresDir = ms4Dir + "/Scores";
var scoresDirWin = scoresDir.replace(/\//g, "\\");
// Per-run script name (temporary)
var runTag = (new Date()).getTime().toString();
var pullBat = pluginDir + "/musescore-git-pull-" + runTag + ".bat";
// ---- only handle .mscz ----
var lastDot = scoreName.lastIndexOf(".");
var nameNoExt = lastDot >= 0 ? scoreName.substring(0, lastDot) : scoreName;
var msczPath = scoresDir + "/" + nameNoExt + ".mscz";
var mscxPath = scoresDir + "/" + nameNoExt + ".mscx";
fileIO.source = msczPath;
var hasMscz = fileIO.exists();
fileIO.source = mscxPath;
var hasMscx = fileIO.exists();
if (!hasMscz) {
if (hasMscx) {
msg.text =
"This plugin only supports .mscz files.\n\n" +
"Please use File → Save As… and save \"" + nameNoExt + "\" as a .mscz file, then run this plugin again.";
} else {
msg.text =
"Couldn't find \"" + nameNoExt + ".mscz\" in your Scores folder.\n\n" +
"Please save the score as a .mscz file, then run this plugin again.";
}
msg.visible = true;
return;
}
// Ensure Scores is a git repo
fileIO.source = scoresDir + "/.git";
if (!fileIO.exists()) {
msg.text =
"Your Scores folder doesn't appear to be a git repository yet.\n\n" +
"Run \"Commit to GitHub\" first-time setup, then try Pull again.";
msg.visible = true;
return;
}
// ---- write pull bat ----
fileIO.source = pullBat;
if (fileIO.exists()) fileIO.remove();
var pullBatWin = pullBat.replace(/\//g, "\\");
var scoreFile = nameNoExt + ".mscz";
fileIO.write([
"@echo off",
"setlocal EnableExtensions",
"cd /d \"" + scoresDirWin + "\"",
"",
"set \"SCORE=" + nameNoExt.replace(/\"/g, "") + "\"",
"set \"SCOREFILE=%SCORE%.mscz\"",
"",
"git fetch origin >nul 2>nul",
"",
"for /f \"delims=\" %%U in ('git rev-parse --abbrev-ref \"@{upstream}\" 2^>nul') do set \"UPSTREAM=%%U\"",
"if not defined UPSTREAM goto doPull",
"",
"REM If remote has changes for this score, try to pull; if it conflicts, fall back to diff.",
"for /f \"delims=\" %%L in ('git log \"HEAD..%UPSTREAM%\" --oneline -- \"%SCOREFILE%\" 2^>nul') do (set \"REMOTE_AHEAD=1\" & goto doPull)",
"",
":doPull",
"git pull --no-edit",
"if errorlevel 1 goto pullFailed",
"",
"powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command \"Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('Pull completed successfully.','Pull from GitHub',[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Information) | Out-Null\"",
"goto end",
"",
":pullFailed",
"REM Abort any in-progress merge so the working tree is clean.",
"git merge --abort >nul 2>nul",
"",
"REM Extract remote version to Scores/<Name> - Copy/<Name> - Copy.mscx for MuseScore Diff.",
"powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -Command \"try { " +
"$sd = (Get-Location).Path; " +
"$nl = [Environment]::NewLine; " +
"$up = git rev-parse --abbrev-ref '@{upstream}' 2>$null; " +
"if (-not $up) { exit }; " +
"$tmp = Join-Path ([IO.Path]::GetTempPath()) ('ms_pull_' + [Guid]::NewGuid().ToString('N').Substring(0,8)); " +
"git worktree add --detach $tmp $up 2>$null | Out-Null; " +
"$remoteFile = Join-Path $tmp $env:SCOREFILE; " +
"$copyDir = Join-Path $sd ($env:SCORE + ' - Copy'); " +
"$copyMscx = Join-Path $copyDir ($env:SCORE + ' - Copy.mscx'); " +
"if (Test-Path $remoteFile) { " +
"Add-Type -AssemblyName System.IO.Compression.FileSystem; " +
"if (-not (Test-Path $copyDir)) { New-Item -ItemType Directory -Path $copyDir | Out-Null }; " +
"$zip = [IO.Compression.ZipFile]::OpenRead($remoteFile); " +
"$entry = $zip.Entries | Where-Object { $_.Name -like '*.mscx' } | Select-Object -First 1; " +
"if ($entry) { [IO.Compression.ZipFileExtensions]::ExtractToFile($entry, $copyMscx, $true) }; " +
"$zip.Dispose(); " +
"}; " +
"git worktree remove --force $tmp 2>$null | Out-Null; " +
"Add-Type -AssemblyName System.Windows.Forms; " +
"[System.Windows.Forms.MessageBox]::Show('Automatic merge was not possible for \"' + $env:SCORE + '\".' + $nl + $nl + " +
"'The remote version has been saved to:' + $nl + ' ' + $copyMscx + $nl + $nl + " +
"'Please run MuseScore Diff to review differences, then commit/push.','Manual Diff Required', " +
"[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Warning) | Out-Null " +
"} catch {}\"",
"",
":end",
"del \"" + pullBatWin + "\""
].join("\r\n"));
Qt.openUrlExternally("file:///" + pullBat.replace(/\\/g, "/"));
quit();
}
}