Skip to content

Commit

Permalink
change branches, check write access, adapt to V2
Browse files Browse the repository at this point in the history
  • Loading branch information
akaJes committed Oct 2, 2017
1 parent 27c74bd commit f835739
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 74 deletions.
13 changes: 11 additions & 2 deletions app/git-tool.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ var gitRoot=(dir)=>
gitRoot().catch(a=>a);

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

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

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

exports.clone=name=>new Promise((done,fail)=>{
var cmd = exec('git clone https://github.com/MarlinFirmware/Marlin.git '+(name||''));
name = name && ('"' + name + '"') || '';
var cmd = exec('git clone https://github.com/MarlinFirmware/Marlin.git ' + name);
var timer = setInterval(a=>process.stdout.write("."), 500)
cmd.stdout.on('data', (data) => {
console.log(data.toString());
Expand Down
85 changes: 49 additions & 36 deletions app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,17 @@ app.get('/tags', function (req, res) {
res.send(data);
});
});
app.get('/branches', function (req, res) {
git.Branches().then(data=>{
res.send(data);
});
});
app.get('/checkout/:branch', function (req, res) {
git.Checkout(req.params.branch)
return Promise.resolve(atob(decodeURI(req.params.branch)).toString())
.then(a=>(console.log(a),a))
.then(git.Checkout)
.then(data=>{
res.send(data);
res.send(data)
})
.catch(a=>res.status(403).send(a))
});
Expand All @@ -194,15 +201,16 @@ var get_cfg=()=>{
.map(f=>{
return base
.then(p=>
git.Show(p[1],path.join(baseCfg,f))
git.Show(p[1], path.join(baseCfg, f)).catch(e => git.Show(p[1], path.join('Marlin', f)))
.then(file=>mctool.getJson(p[0],file,p[1])(path.join(p[0],'Marlin',f)))
)
.then(o=>(o.names.filter(n=>hints.d2i(n.name),1).map(n=>o.defs[n.name].hint=!0),o))
.then(a=>(a.names=undefined,type='file',a))
.then(a=>
(!a.defs['MOTHERBOARD']&&a)||
base
.then(p=>mctool.getBoards(path.join(p[0],'Marlin','boards.h')))
seek4File('boards.h', [ 'Marlin', path.join('Marlin', 'src', 'core')])
.then(mctool.getBoards)
.catch(e => '' )
.then(boards=>(Object.assign(a.defs['MOTHERBOARD'],{select:boards,type:"select"}),a))
)
});
Expand All @@ -213,40 +221,39 @@ app.get('/now/', function (req, res) { //???
get_cfg().then(a=>res.send(JSON.stringify(a,null,2)))
});
var unique=a=>a.filter((elem, index, self)=>index == self.indexOf(elem))
var ex_dir = (rel) => seek4File('', [path.join('Marlin', 'example_configurations'), path.join('Marlin', 'src', 'config', 'examples')], rel)
app.get('/examples', function (req, res) {
git.root()
.then(root=>{
var ex=path.join(root,'Marlin','example_configurations')
return walk(ex)
var ex;
return ex_dir()
.then(dir => (ex = dir))
.then(walk)
.then(a=>a.filter(i=>/Configuration(_adv)?\.h/.test(i)))
.then(a=>a.map(i=>path.parse(path.relative(ex,i)).dir))
.then(unique)
.catch(e => [])
.then(a=>(a.unshift('Marlin'),a))
.then(a=>res.send({current:baseCfg,list:a}))
})
});
app.get('/set-base/:path', function (req, res) {
baseCfg=atob(decodeURI(req.params.path)).toString();
if (baseCfg!='Marlin')
baseCfg=path.join('Marlin','example_configurations',baseCfg);
res.end();
return Promise.resolve(atob(decodeURI(req.params.path)).toString())
.then(base => base == 'Marlin' && base || ex_dir(1).then(ex => path.join(ex, base)) )
.then(base => res.send(baseCfg = base))
});
app.get('/status', function (req, res) {
git.Status().then(a=>res.send(a))
});
app.get('/checkout-force', function (req, res) {
var cp=baseCfg=='Marlin'?a=>a:a=>
git.root()
.then(root=>
['Configuration.h','Configuration_adv.h']
var cp = () => git.root()
.then(root => Promise.all(
['Configuration.h', 'Configuration_adv.h', '_Bootscreen.h']
.map(f=>new Promise((done,fail)=>
fs.createReadStream(path.join(root,baseCfg,f))
.pipe(fs.createWriteStream(path.join(root,'Marlin',f)).on('finish',done))
)
fs.createReadStream(path.join(root, baseCfg, f)).on('error', fail)
.pipe(fs.createWriteStream(path.join(root, 'Marlin', f)).on('finish', done))
).catch(e => 'not found')
)
)
))
git.Checkout('--force')
.then(cp)
.then(a => baseCfg == 'Marlin' && a || cp())
.then(a=>res.send(a));
});
app.get('/fetch', function (req, res) {
Expand Down Expand Up @@ -373,18 +380,19 @@ app.get('/version', function (req, res) {
res.set('Content-Type', 'image/svg+xml');
var badge={
text: { name:pjson.name, version:pjson.version },
width: { text:83, version:39, total:122 },
width: { text: 83, version: 45 },
position: { version:88 }
};
badge.width.total = badge.width.text + badge.width.version;

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

function pioRoot(){
return git.root()
.then(root=>
promisify(fs.stat)(path.join(root,'Marlin','platformio.ini'))
.then(a=>path.join(root,'Marlin'))
.catch(a=>root)
.then(root=>(process.chdir(root),root))
);
return seek4File('platformio.ini', ['', 'Marlin'])
}
app.get('/pio/:env', function (req, res) {
params=['run'];
Expand Down Expand Up @@ -481,8 +483,7 @@ function getMatch(reg,data,second){
return m[1];
}
app.get('/bs/default', function (req, res) {
git.root()
.then(f=>path.join(f,'Marlin','dogm_bitmaps.h'))
return seek4File('dogm_bitmaps.h', ['Marlin', path.join('Marlin', 'src', 'lcd', 'dogm')])
.then(file=>promisify(fs.readFile)(file,'utf8'))
.then(data=>{
var second=/\/\/\s*#define\s+START_BMPHIGH/g.test(data);
Expand Down Expand Up @@ -539,6 +540,18 @@ app.get('/gcodes', function (req, res) {

/* MAIN */

function getFirstFile(paths) {
if (!paths || paths.length == 0)
return Promise.reject();
var filePath = paths.shift();
return promisify(fs.access)(filePath, fs.constants.R_OK)
.then(a => filePath)
.catch(e => getFirstFile(paths) );
}
function seek4File(file, paths, rel) {
return git.root().then(root => getFirstFile(paths.map(i => path.join(root, i, file))).then(res => rel && path.relative(root, res) || res))
}

app.get('/json/', function (req, res) {
res.set('Content-Type', 'application/json');
get_cfg().then(a=>res.send(a))
Expand Down
50 changes: 25 additions & 25 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const notifier = require('node-notifier');

var which=require('which');
var path=require('path');
var fs = require('fs');
var promisify = require('./app/helpers').promisify;
var git = require('./app/git-tool');
var server = require('./app/server');
Expand All @@ -16,7 +17,7 @@ var getFolder=()=>new Promise((done,fail)=>
title:'select folder with Marlin Firmware or empty folder to clone it',
properties:['openDirectory'],
},function(folders){
console.log();
console.log(); //without this - it hangs
if (!folders)
return fail({type:'fatal',message:'no folder selected'});
done(folders[0])
Expand All @@ -35,33 +36,28 @@ function showNotify(text){
});
}
app.on('ready', function() {
var folder;
promisify(which)('git')
.catch(function(){
dialog.showErrorBox('Dependecies','Application needs GIT to be installed!')
throw {type:'fatal',message:'no Git installed'};
})
.then(function(){
var is={'-G':0}
.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));
if (!is['-G'])
return getFolder();
return is['-G'];
})
.then(f=>folder=f)
.then(git.root)
.catch(function(e){
if (e&&e.type=="fatal")
throw e;
console.log('no repository found in this folder');
showNotify('Wait while Marlin Firmware repo cloning');
return git.clone(path.join(folder,'Marlin')).then(git.root).then(a=>(showNotify('Well done!'),a));
})
.catch(function(e){
if (e&&e.type=="fatal")
throw e;
return git.root(path.join(folder,'Marlin'));
var chain = () => getFolder().then(dir =>
promisify(fs.access)(dir, fs.constants.W_OK)
.then(a => dir)
.catch(e => (dialog.showErrorBox('Access','The application hasn\'t access to this folder,\nselect a folder from my Documents or Desktop'),chain()))
);
return is['-G'] || chain();
})
.then(dir => git.root(dir)
.catch(e => {
console.log('no repository found in this folder');
showNotify('Wait while Marlin Firmware repo cloning');
dir = path.join(dir, 'Marlin')
return git.clone(dir)
.then(git.root)
.then(a => showNotify('Well done!'))
.catch(e => git.root(dir));
})
)
.then(()=>server.main(1))
.then(function(url){
mainWindow = new BrowserWindow({
Expand All @@ -74,8 +70,12 @@ app.on('ready', function() {
});
mainWindow.loadURL(url);
})
.catch(function(e){
console.error(e.message)
.catch(e => {
console.error(e.message);
if (e.message == 'not found: git')
dialog.showErrorBox('Dependecies','The application needs a GIT tool to be installed!\nhttps://git-scm.com/downloads')
else
dialog.showErrorBox('Error', e.message);
app.quit();
})
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "marlin-conf",
"version": "2.7.11",
"version": "2.7.12",
"description": "configuration tool for Marlin project",
"main": "./index.js",
"scripts": {
Expand All @@ -10,7 +10,7 @@
"dist": "GH_TOKEN=`./node_modules/.bin/json -f ~/.github.json -c 'console.log(this.OAuth)'` build -mwl --x64 --ia32 -p always",
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint .",
"rebuild": "npm rebuild serialport-v4 --update-binary",
"rebuild": "npm rebuild serialport@6.0.0-beta1 --update-binary",
"prepublish": "./node_modules/.bin/json -I -f package.json -e 'if(this.devDependencies)this.devDependenciesOff=this.devDependencies;this.devDependencies=undefined'",
"postpublish": "./node_modules/.bin/json -I -f package.json -e 'if(this.devDependenciesOff)this.devDependencies=this.devDependenciesOff;this.devDependenciesOff=undefined'",
"prebuild-": "sudo apt install icnsutils graphicsmagick"
Expand Down
15 changes: 12 additions & 3 deletions static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@
.form-group {
margin-bottom: .5rem;
}
#mct-examples-modal .modal-body {
max-height: 500px;
overflow-y: auto;
}
#mct-tags-modal .modal-body {
max-height: 500px;
overflow-y: auto;
}
</style>
<script>
//open links externally by default
Expand Down Expand Up @@ -336,11 +344,12 @@ <h5 class="modal-title" id="mct-restoreModalLabel">Choose desired configuration
<ul class="navbar-nav mr-auto">
<li class="nav-item mr-sm-2 my-auto p-1">
<div class="dropdown d-inline-block">
<button class="btn btn-info dropdown-toggle mct-tags" title="Current release" id="dropdownTagsLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<button class="btn btn-info dropdown-toggle mct-tag" title="Current release" id="dropdownTagsLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
TAGS
</button>
<div class="dropdown-menu" aria-labelledby="dropdownTagsLink">
<button class="dropdown-item mct-change" title="Change version (git checkout)" >Change</button>
<button class="dropdown-item mct-tags" title="Change version (Releases)" >Change</button>
<button class="dropdown-item mct-branches" title="Change version (Development verions - these can be unstable!!!)" >Branches</button>
<button class="dropdown-item mct-update" title="Update version list from GitHub (git fetch)">Update</button>
<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>
<button class="dropdown-item mct-examples" title="Choose base file from examples">Examples</button>
Expand All @@ -360,7 +369,7 @@ <h5 class="modal-title" id="mct-restoreModalLabel">Choose desired configuration
</label>
</div>
<div class="dropdown d-inline-block">
<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>
<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>
<div class="dropdown-menu" aria-labelledby="dropdownUploadLink">
<button class="dropdown-item bg-warning mct-upload" title="Upload your old configuration or drag it in browser">Files</button>
<button class="dropdown-item mct-restore" title="Get files from storage">Saved</button>
Expand Down
16 changes: 10 additions & 6 deletions static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ $(function(){
})
}
})
$('.mct-tags').eq(0).text(file.tag)
$('.mct-tag').eq(0).text(file.tag)
var href='card-'+file.file.name;
var tab=addNewTab(file.file.name,href)
$.each(file.sections,function(n,section){
Expand Down Expand Up @@ -493,21 +493,22 @@ $(function(){
})
});
// tag menu - change
(function(btn,ui){
var tags = function(btn, ui, url){
var t=ui.find('table tbody');
ui.find('button.btn-primary').on('click',function(ev){
var row = t.find('.table-success');
if(row.length){
var tag=row.find('td').eq(1).text().split(',');
cmdReload($.ajax('/checkout/'+tag[0]),ui);
var tag=row.find('td').eq(1).text().split(',')[0];
console.log(tag);
cmdReload($.ajax('/checkout/' + encodeURI(btoa(tag))),ui);
}
});
ui.find('table tbody').on('click',function(ev){
$(this).find('tr').removeClass('table-success');
$(ev.target).parents('tr').addClass('table-success')
});
btn.on('click',function(){
$.ajax('/tags')
$.ajax(url)
.fail(ajaxAlert)
.then(function(data){
data=data.sort(function(a,b){ return a.date<b.date?1:a.date>b.date?-1:0;})
Expand All @@ -518,7 +519,10 @@ $(function(){
ui.modal();
})
})
}($('.mct-change'),$('#mct-tags-modal')));
return this;
}
tags($('.mct-tags'),$('#mct-tags-modal'),'/tags');
tags($('.mct-branches'),$('#mct-tags-modal'),'/branches');
// tag menu - examples
(function(btn,ui){
var t=ui.find('table tbody');
Expand Down
Loading

0 comments on commit f835739

Please sign in to comment.