From 909daa39c9ac02b9deaffe58f628617257d2cb9e Mon Sep 17 00:00:00 2001 From: Louis Orleans Date: Sun, 10 Sep 2017 19:15:00 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=89=20Building=20simple=20flasher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flasher/.gitignore | 1 + flasher/commands.js | 47 +++++++++++ flasher/index.js | 29 +++++++ flasher/package.json | 22 ++++++ flasher/util.js | 42 ++++++++++ flasher/yarn.lock | 184 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 325 insertions(+) create mode 100644 flasher/.gitignore create mode 100644 flasher/commands.js create mode 100755 flasher/index.js create mode 100644 flasher/package.json create mode 100644 flasher/util.js create mode 100644 flasher/yarn.lock diff --git a/flasher/.gitignore b/flasher/.gitignore new file mode 100644 index 0000000000..3c3629e647 --- /dev/null +++ b/flasher/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/flasher/commands.js b/flasher/commands.js new file mode 100644 index 0000000000..f11c0e3c55 --- /dev/null +++ b/flasher/commands.js @@ -0,0 +1,47 @@ +module.exports.Upload = async function Upload (keymap, target, right = false) { + await build(right); + + let board; + while (board == null) { + board = IdentifyKeyboard(); + if (board == null) { + Echo(`Put your keyboard in flash mode`); + } + } + + Echo(`Building for ${board.name}`); + await flash(right, board); +} + +module.exports.Build = async function Build (right = false) { + Echo(`Building ${right ? 'right' : 'left'}`); + await Exec(`make ergodox_infinity-${KEYMAP} ${right ? 'MASTER=right' : ''}`); + Echo(`Built ${right ? 'right' : 'left'}`, ''); +} + +module.exports.Flash = function Flash (right = false, board) { + return new Promise(async resolve => { + Echo(`Flashing ${right ? 'right' : 'left'}`); + try { + await Exec(`make ergodox_infinity-${KEYMAP}-dfu-util ${right ? 'MASTER=right' : ''}`); + } catch (err) { + if (err.message && err.message.includes(`More than one DFU capable USB device found`)) { + Echo(`QMK flash failed!`); + Echo(`Flashing manually with dfu-util`); + + await Exec(`dfu-util --device ${board.id} -D .build/ergodox_infinity_default.bin`); + } else { + throw err; + } + } + Echo(`Flashed ${right ? 'right' : 'left'}`, ''); + + // while (IdentifyKeyboard()) { + // Echo(`Unplug your keyboard!`); + // } + // TODO: Check to see if the script is done. If it is, then don't require an unplug + // TODO: Make this actually look for the keyboard to be unplugged + Echo(`Unplug your keyboard! (you have 15 seconds to do so)`); + setTimeout(() => resolve(), 15000); + }); +} diff --git a/flasher/index.js b/flasher/index.js new file mode 100755 index 0000000000..cea1e1cb34 --- /dev/null +++ b/flasher/index.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node + +const { execSync, exec } = require('child_process'); + +const { Echo, Exec, IdentifyKeyboard } = require('./util'); +const { Upload } = require('./commands'); + +const KEYMAP = process.env.KEYMAP || 'default'; +const LEFT_TARGET = process.env.LEFT; +const RIGHT_TARGET = process.env.RIGHT; + +(async () => { + Echo(`Keymap: ${KEYMAP}`); + + if (process.env.LEFT || process.env.RIGHT) { + if (process.env.LEFT) { + await Upload(KEYMAP); + } + + if (process.env.RIGHT) { + await Upload(KEYMAP, undefined, true); + } + } else { + // Build both halves + await Upload(KEYMAP); + + await Upload(KEYMAP, undefined, true); + } +})(); diff --git a/flasher/package.json b/flasher/package.json new file mode 100644 index 0000000000..cb2fa7bd8d --- /dev/null +++ b/flasher/package.json @@ -0,0 +1,22 @@ +{ + "name": "flasher", + "version": "1.0.0", + "description": "QMK flashing utility", + "main": "index.js", + "author": { + "name": "Louis Orleans" + }, + "license": "MIT", + "private": true, + "engines": { + "node": ">=8.0.0" + }, + "os": [ + "!win32" + ], + "dependencies": { + "chalk": "^2.1.0", + "commander": "^2.11.0", + "inquirer": "^3.2.3" + } +} diff --git a/flasher/util.js b/flasher/util.js new file mode 100644 index 0000000000..0874b56d06 --- /dev/null +++ b/flasher/util.js @@ -0,0 +1,42 @@ +const Chalk = require('chalk'); + +module.exports.IdentifyKeyboard = function IdentifyKeyboard (name = 'Kiibohd DFU', path, limit = true) { + const boards = execSync(`dfu-util --list`).toString() + .split('\n') + .filter(line => line.match(/(\[\w+\:\w+\])/g) != null) + .map(line => ({ + name: /name="([\w\s]+)"/g.exec(line)[1], + id: /(\[\w+\:\w+\])/g.exec(line)[1] + })) + .filter(device => device.name === name && path != null ? device.path === path : true); + if (limit) { + return boards[0]; + } else { + return boards; + } +} + +module.exports.Exec = function Exec (command) { + return new Promise((resolve, reject) => { + console.log(command); + const proc = exec(command, (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + const line_start = Chalk.blue(']\t'); + proc.stdout.on('data', data => console.log(line_start + data.replace(/\n$/, '').replace(/\n/g, `\n${line_start}`))); + }); +} + +module.exports.Echo = function Echo (...logs) { + for(const log of logs) { + if (typeof log === 'string') { + console.log(log); + } else { + console.log(log.toString ? log.toString() : log); + } + } +} diff --git a/flasher/yarn.lock b/flasher/yarn.lock new file mode 100644 index 0000000000..f3f67f2b4d --- /dev/null +++ b/flasher/yarn.lock @@ -0,0 +1,184 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +chalk@^2.0.0, chalk@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +color-convert@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +commander@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +iconv-lite@^0.4.17: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +inquirer@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.3.tgz#1c7b1731cf77b934ec47d22c9ac5aa8fe7fbe095" + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +jschardet@^1.4.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.1.tgz#c519f629f86b3a5bedba58a88d311309eec097f9" + +lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +os-tmpdir@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +supports-color@^4.0.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" + dependencies: + has-flag "^2.0.0" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1"