Skip to content

Commit f835739

Browse files
committed
change branches, check write access, adapt to V2
1 parent 27c74bd commit f835739

File tree

8 files changed

+121
-74
lines changed

8 files changed

+121
-74
lines changed

app/git-tool.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ var gitRoot=(dir)=>
1313
gitRoot().catch(a=>a);
1414

1515
var gitTag=()=>
16-
new Promise((done,fail)=>git(root).raw(['describe','--tags'],(e,a)=>e?fail(e):done(a.replace(/\r|\n/,''))))
16+
new Promise((done,fail)=>git(root).raw(['describe','--all'],(e,a)=>e?fail(e):done(a.replace(/\r|\n/,''))))
17+
.then(root=>root.replace(/remotes\//,""))
1718
.then(root=>(console.log('[gitTag]',root),root))
1819
.catch(mst=>console.log('no tag'))
1920

@@ -28,6 +29,13 @@ new Promise((done,fail)=>git(root).log(['--tags','--simplify-by-decoration'],(e,
2829
.then(root=>(verbose&&console.log('[gitTags]',root),root))
2930
.catch(mst=>console.log('no tags'))
3031

32+
var branch_f='{"hash":"%(objectname:short)","date":"%(committerdate:iso)","ref":"%(refname)"},';
33+
exports.Branches = () => {
34+
return promisify('raw',git(root))(['for-each-ref','refs/remotes','--sort=-committerdate',"--format=" + branch_f])
35+
.then(txt => JSON.parse('[' + txt.slice(0, -2) + ']')) //TODO:check windows
36+
.then(list => list.map(i => (i.tag=i.ref.replace(/refs\/remotes\/(.*)/,"$1"),i)))
37+
.catch(e => [])
38+
}
3139
exports.Checkout=(branch)=>promisify('checkout',git(root))(branch);
3240
exports.Status=()=>promisify('status',git(root))();
3341
exports.Fetch=()=>promisify('fetch',git(root))(['--all']);
@@ -38,7 +46,8 @@ exports.git=git;
3846
exports.root=a=>a?gitRoot(a):root?Promise.resolve(root):Promise.reject();
3947

4048
exports.clone=name=>new Promise((done,fail)=>{
41-
var cmd = exec('git clone https://github.com/MarlinFirmware/Marlin.git '+(name||''));
49+
name = name && ('"' + name + '"') || '';
50+
var cmd = exec('git clone https://github.com/MarlinFirmware/Marlin.git ' + name);
4251
var timer = setInterval(a=>process.stdout.write("."), 500)
4352
cmd.stdout.on('data', (data) => {
4453
console.log(data.toString());

app/server.js

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,17 @@ app.get('/tags', function (req, res) {
181181
res.send(data);
182182
});
183183
});
184+
app.get('/branches', function (req, res) {
185+
git.Branches().then(data=>{
186+
res.send(data);
187+
});
188+
});
184189
app.get('/checkout/:branch', function (req, res) {
185-
git.Checkout(req.params.branch)
190+
return Promise.resolve(atob(decodeURI(req.params.branch)).toString())
191+
.then(a=>(console.log(a),a))
192+
.then(git.Checkout)
186193
.then(data=>{
187-
res.send(data);
194+
res.send(data)
188195
})
189196
.catch(a=>res.status(403).send(a))
190197
});
@@ -194,15 +201,16 @@ var get_cfg=()=>{
194201
.map(f=>{
195202
return base
196203
.then(p=>
197-
git.Show(p[1],path.join(baseCfg,f))
204+
git.Show(p[1], path.join(baseCfg, f)).catch(e => git.Show(p[1], path.join('Marlin', f)))
198205
.then(file=>mctool.getJson(p[0],file,p[1])(path.join(p[0],'Marlin',f)))
199206
)
200207
.then(o=>(o.names.filter(n=>hints.d2i(n.name),1).map(n=>o.defs[n.name].hint=!0),o))
201208
.then(a=>(a.names=undefined,type='file',a))
202209
.then(a=>
203210
(!a.defs['MOTHERBOARD']&&a)||
204-
base
205-
.then(p=>mctool.getBoards(path.join(p[0],'Marlin','boards.h')))
211+
seek4File('boards.h', [ 'Marlin', path.join('Marlin', 'src', 'core')])
212+
.then(mctool.getBoards)
213+
.catch(e => '' )
206214
.then(boards=>(Object.assign(a.defs['MOTHERBOARD'],{select:boards,type:"select"}),a))
207215
)
208216
});
@@ -213,40 +221,39 @@ app.get('/now/', function (req, res) { //???
213221
get_cfg().then(a=>res.send(JSON.stringify(a,null,2)))
214222
});
215223
var unique=a=>a.filter((elem, index, self)=>index == self.indexOf(elem))
224+
var ex_dir = (rel) => seek4File('', [path.join('Marlin', 'example_configurations'), path.join('Marlin', 'src', 'config', 'examples')], rel)
216225
app.get('/examples', function (req, res) {
217-
git.root()
218-
.then(root=>{
219-
var ex=path.join(root,'Marlin','example_configurations')
220-
return walk(ex)
226+
var ex;
227+
return ex_dir()
228+
.then(dir => (ex = dir))
229+
.then(walk)
221230
.then(a=>a.filter(i=>/Configuration(_adv)?\.h/.test(i)))
222231
.then(a=>a.map(i=>path.parse(path.relative(ex,i)).dir))
223232
.then(unique)
233+
.catch(e => [])
224234
.then(a=>(a.unshift('Marlin'),a))
225235
.then(a=>res.send({current:baseCfg,list:a}))
226-
})
227236
});
228237
app.get('/set-base/:path', function (req, res) {
229-
baseCfg=atob(decodeURI(req.params.path)).toString();
230-
if (baseCfg!='Marlin')
231-
baseCfg=path.join('Marlin','example_configurations',baseCfg);
232-
res.end();
238+
return Promise.resolve(atob(decodeURI(req.params.path)).toString())
239+
.then(base => base == 'Marlin' && base || ex_dir(1).then(ex => path.join(ex, base)) )
240+
.then(base => res.send(baseCfg = base))
233241
});
234242
app.get('/status', function (req, res) {
235243
git.Status().then(a=>res.send(a))
236244
});
237245
app.get('/checkout-force', function (req, res) {
238-
var cp=baseCfg=='Marlin'?a=>a:a=>
239-
git.root()
240-
.then(root=>
241-
['Configuration.h','Configuration_adv.h']
246+
var cp = () => git.root()
247+
.then(root => Promise.all(
248+
['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h']
242249
.map(f=>new Promise((done,fail)=>
243-
fs.createReadStream(path.join(root,baseCfg,f))
244-
.pipe(fs.createWriteStream(path.join(root,'Marlin',f)).on('finish',done))
245-
)
250+
fs.createReadStream(path.join(root, baseCfg, f)).on('error', fail)
251+
.pipe(fs.createWriteStream(path.join(root, 'Marlin', f)).on('finish', done))
252+
).catch(e => 'not found')
246253
)
247-
)
254+
))
248255
git.Checkout('--force')
249-
.then(cp)
256+
.then(a => baseCfg == 'Marlin' && a || cp())
250257
.then(a=>res.send(a));
251258
});
252259
app.get('/fetch', function (req, res) {
@@ -373,18 +380,19 @@ app.get('/version', function (req, res) {
373380
res.set('Content-Type', 'image/svg+xml');
374381
var badge={
375382
text: { name:pjson.name, version:pjson.version },
376-
width: { text:83, version:39, total:122 },
383+
width: { text: 83, version: 45 },
377384
position: { version:88 }
378385
};
386+
badge.width.total = badge.width.text + badge.width.version;
379387

380388
var file=path.join(__dirname,'..','views','version.html');
381389
return promisify(fs.readFile)(file,'utf8')
382390
.then(v=>{
383391
res.end(v.replace(/{{([\w.]+)}}/g,(m,r)=>r.split('.').reduce((p,o)=>(p=p&&p[o],p),badge)));
384392
});
385393
});
386-
var pioEnv=(dir)=>
387-
promisify(fs.readFile)(path.join(dir,'platformio.ini'),'utf8')
394+
var pioEnv = (file) =>
395+
promisify(fs.readFile)(file, 'utf8')
388396
.then(a=>a.split(/\r\n?|\n/))
389397
.then(a=>a.map(i=>i.match(/\[env\:(.*)\]/)).filter(i=>i).map(i=>i[1]))
390398
app.get('/version/:screen', function (req, res) {
@@ -396,7 +404,7 @@ app.get('/version/:screen', function (req, res) {
396404
ua:req.headers['user-agent'],
397405
ul:req.headers['accept-language'].split(',')[0],
398406
}).send()
399-
Promise.all([pio.isPIO().catch(()=>false),git.root(),git.root().then(pioEnv)])
407+
Promise.all([pio.isPIO().catch(() => false), git.root(), pioRoot().then(pioEnv).catch(e => [])])
400408
.then(pp=>{
401409
//console.log(a)
402410
var cfg={pio:pp[0],version:pjson.version,root:pp[1],base:baseCfg,env:pp[2]};
@@ -408,13 +416,7 @@ app.get('/version/:screen', function (req, res) {
408416
/* PIO */
409417

410418
function pioRoot(){
411-
return git.root()
412-
.then(root=>
413-
promisify(fs.stat)(path.join(root,'Marlin','platformio.ini'))
414-
.then(a=>path.join(root,'Marlin'))
415-
.catch(a=>root)
416-
.then(root=>(process.chdir(root),root))
417-
);
419+
return seek4File('platformio.ini', ['', 'Marlin'])
418420
}
419421
app.get('/pio/:env', function (req, res) {
420422
params=['run'];
@@ -481,8 +483,7 @@ function getMatch(reg,data,second){
481483
return m[1];
482484
}
483485
app.get('/bs/default', function (req, res) {
484-
git.root()
485-
.then(f=>path.join(f,'Marlin','dogm_bitmaps.h'))
486+
return seek4File('dogm_bitmaps.h', ['Marlin', path.join('Marlin', 'src', 'lcd', 'dogm')])
486487
.then(file=>promisify(fs.readFile)(file,'utf8'))
487488
.then(data=>{
488489
var second=/\/\/\s*#define\s+START_BMPHIGH/g.test(data);
@@ -539,6 +540,18 @@ app.get('/gcodes', function (req, res) {
539540

540541
/* MAIN */
541542

543+
function getFirstFile(paths) {
544+
if (!paths || paths.length == 0)
545+
return Promise.reject();
546+
var filePath = paths.shift();
547+
return promisify(fs.access)(filePath, fs.constants.R_OK)
548+
.then(a => filePath)
549+
.catch(e => getFirstFile(paths) );
550+
}
551+
function seek4File(file, paths, rel) {
552+
return git.root().then(root => getFirstFile(paths.map(i => path.join(root, i, file))).then(res => rel && path.relative(root, res) || res))
553+
}
554+
542555
app.get('/json/', function (req, res) {
543556
res.set('Content-Type', 'application/json');
544557
get_cfg().then(a=>res.send(a))

index.js

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const notifier = require('node-notifier');
66

77
var which=require('which');
88
var path=require('path');
9+
var fs = require('fs');
910
var promisify = require('./app/helpers').promisify;
1011
var git = require('./app/git-tool');
1112
var server = require('./app/server');
@@ -16,7 +17,7 @@ var getFolder=()=>new Promise((done,fail)=>
1617
title:'select folder with Marlin Firmware or empty folder to clone it',
1718
properties:['openDirectory'],
1819
},function(folders){
19-
console.log();
20+
console.log(); //without this - it hangs
2021
if (!folders)
2122
return fail({type:'fatal',message:'no folder selected'});
2223
done(folders[0])
@@ -35,33 +36,28 @@ function showNotify(text){
3536
});
3637
}
3738
app.on('ready', function() {
38-
var folder;
3939
promisify(which)('git')
40-
.catch(function(){
41-
dialog.showErrorBox('Dependecies','Application needs GIT to be installed!')
42-
throw {type:'fatal',message:'no Git installed'};
43-
})
4440
.then(function(){
4541
var is={'-G':0}
4642
.filter((v,key,o,p,i)=>(p=process.argv,i=p.indexOf(key),!v&&i>=0&&i+1<p.length&&(o[key]=p[i+1]),i>=0));
47-
if (!is['-G'])
48-
return getFolder();
49-
return is['-G'];
50-
})
51-
.then(f=>folder=f)
52-
.then(git.root)
53-
.catch(function(e){
54-
if (e&&e.type=="fatal")
55-
throw e;
56-
console.log('no repository found in this folder');
57-
showNotify('Wait while Marlin Firmware repo cloning');
58-
return git.clone(path.join(folder,'Marlin')).then(git.root).then(a=>(showNotify('Well done!'),a));
59-
})
60-
.catch(function(e){
61-
if (e&&e.type=="fatal")
62-
throw e;
63-
return git.root(path.join(folder,'Marlin'));
43+
var chain = () => getFolder().then(dir =>
44+
promisify(fs.access)(dir, fs.constants.W_OK)
45+
.then(a => dir)
46+
.catch(e => (dialog.showErrorBox('Access','The application hasn\'t access to this folder,\nselect a folder from my Documents or Desktop'),chain()))
47+
);
48+
return is['-G'] || chain();
6449
})
50+
.then(dir => git.root(dir)
51+
.catch(e => {
52+
console.log('no repository found in this folder');
53+
showNotify('Wait while Marlin Firmware repo cloning');
54+
dir = path.join(dir, 'Marlin')
55+
return git.clone(dir)
56+
.then(git.root)
57+
.then(a => showNotify('Well done!'))
58+
.catch(e => git.root(dir));
59+
})
60+
)
6561
.then(()=>server.main(1))
6662
.then(function(url){
6763
mainWindow = new BrowserWindow({
@@ -74,8 +70,12 @@ app.on('ready', function() {
7470
});
7571
mainWindow.loadURL(url);
7672
})
77-
.catch(function(e){
78-
console.error(e.message)
73+
.catch(e => {
74+
console.error(e.message);
75+
if (e.message == 'not found: git')
76+
dialog.showErrorBox('Dependecies','The application needs a GIT tool to be installed!\nhttps://git-scm.com/downloads')
77+
else
78+
dialog.showErrorBox('Error', e.message);
7979
app.quit();
8080
})
8181
});

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "marlin-conf",
3-
"version": "2.7.11",
3+
"version": "2.7.12",
44
"description": "configuration tool for Marlin project",
55
"main": "./index.js",
66
"scripts": {
@@ -10,7 +10,7 @@
1010
"dist": "GH_TOKEN=`./node_modules/.bin/json -f ~/.github.json -c 'console.log(this.OAuth)'` build -mwl --x64 --ia32 -p always",
1111
"test": "echo \"Error: no test specified\" && exit 1",
1212
"lint": "eslint .",
13-
"rebuild": "npm rebuild serialport-v4 --update-binary",
13+
"rebuild": "npm rebuild serialport@6.0.0-beta1 --update-binary",
1414
"prepublish": "./node_modules/.bin/json -I -f package.json -e 'if(this.devDependencies)this.devDependenciesOff=this.devDependencies;this.devDependencies=undefined'",
1515
"postpublish": "./node_modules/.bin/json -I -f package.json -e 'if(this.devDependenciesOff)this.devDependencies=this.devDependenciesOff;this.devDependenciesOff=undefined'",
1616
"prebuild-": "sudo apt install icnsutils graphicsmagick"

static/index.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@
105105
.form-group {
106106
margin-bottom: .5rem;
107107
}
108+
#mct-examples-modal .modal-body {
109+
max-height: 500px;
110+
overflow-y: auto;
111+
}
112+
#mct-tags-modal .modal-body {
113+
max-height: 500px;
114+
overflow-y: auto;
115+
}
108116
</style>
109117
<script>
110118
//open links externally by default
@@ -336,11 +344,12 @@ <h5 class="modal-title" id="mct-restoreModalLabel">Choose desired configuration
336344
<ul class="navbar-nav mr-auto">
337345
<li class="nav-item mr-sm-2 my-auto p-1">
338346
<div class="dropdown d-inline-block">
339-
<button class="btn btn-info dropdown-toggle mct-tags" title="Current release" id="dropdownTagsLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
347+
<button class="btn btn-info dropdown-toggle mct-tag" title="Current release" id="dropdownTagsLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
340348
TAGS
341349
</button>
342350
<div class="dropdown-menu" aria-labelledby="dropdownTagsLink">
343-
<button class="dropdown-item mct-change" title="Change version (git checkout)" >Change</button>
351+
<button class="dropdown-item mct-tags" title="Change version (Releases)" >Change</button>
352+
<button class="dropdown-item mct-branches" title="Change version (Development verions - these can be unstable!!!)" >Branches</button>
344353
<button class="dropdown-item mct-update" title="Update version list from GitHub (git fetch)">Update</button>
345354
<button class="dropdown-item bg-danger text-white mct-reset" title="Reset all changes (git checkout -f) or copy from examples if choosen">Reset</button>
346355
<button class="dropdown-item mct-examples" title="Choose base file from examples">Examples</button>
@@ -360,7 +369,7 @@ <h5 class="modal-title" id="mct-restoreModalLabel">Choose desired configuration
360369
</label>
361370
</div>
362371
<div class="dropdown d-inline-block">
363-
<button class="btn btn-warning dropdown-toggle mct-tags" id="dropdownUploadLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="update current configuration from files or store">Upload</button>
372+
<button class="btn btn-warning dropdown-toggle" id="dropdownUploadLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="update current configuration from files or store">Upload</button>
364373
<div class="dropdown-menu" aria-labelledby="dropdownUploadLink">
365374
<button class="dropdown-item bg-warning mct-upload" title="Upload your old configuration or drag it in browser">Files</button>
366375
<button class="dropdown-item mct-restore" title="Get files from storage">Saved</button>

static/main.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ $(function(){
307307
})
308308
}
309309
})
310-
$('.mct-tags').eq(0).text(file.tag)
310+
$('.mct-tag').eq(0).text(file.tag)
311311
var href='card-'+file.file.name;
312312
var tab=addNewTab(file.file.name,href)
313313
$.each(file.sections,function(n,section){
@@ -493,21 +493,22 @@ $(function(){
493493
})
494494
});
495495
// tag menu - change
496-
(function(btn,ui){
496+
var tags = function(btn, ui, url){
497497
var t=ui.find('table tbody');
498498
ui.find('button.btn-primary').on('click',function(ev){
499499
var row = t.find('.table-success');
500500
if(row.length){
501-
var tag=row.find('td').eq(1).text().split(',');
502-
cmdReload($.ajax('/checkout/'+tag[0]),ui);
501+
var tag=row.find('td').eq(1).text().split(',')[0];
502+
console.log(tag);
503+
cmdReload($.ajax('/checkout/' + encodeURI(btoa(tag))),ui);
503504
}
504505
});
505506
ui.find('table tbody').on('click',function(ev){
506507
$(this).find('tr').removeClass('table-success');
507508
$(ev.target).parents('tr').addClass('table-success')
508509
});
509510
btn.on('click',function(){
510-
$.ajax('/tags')
511+
$.ajax(url)
511512
.fail(ajaxAlert)
512513
.then(function(data){
513514
data=data.sort(function(a,b){ return a.date<b.date?1:a.date>b.date?-1:0;})
@@ -518,7 +519,10 @@ $(function(){
518519
ui.modal();
519520
})
520521
})
521-
}($('.mct-change'),$('#mct-tags-modal')));
522+
return this;
523+
}
524+
tags($('.mct-tags'),$('#mct-tags-modal'),'/tags');
525+
tags($('.mct-branches'),$('#mct-tags-modal'),'/branches');
522526
// tag menu - examples
523527
(function(btn,ui){
524528
var t=ui.find('table tbody');

0 commit comments

Comments
 (0)