From 1882a8024e4cec0be568436edde461c70039f994 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Wed, 13 Sep 2017 16:33:49 +0000 Subject: [PATCH 01/12] Fix:Add to langmap not set ino,pde using ctags --- Arduino.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arduino.mk b/Arduino.mk index 107bdc3..b964d42 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -1605,7 +1605,7 @@ ifneq ($(words $(wildcard $(TAGS_FILE))), 0) rm -f $(TAGS_FILE) endif @$(ECHO) "Generating tags for local sources (INO an PDE files as C++): " - $(CTAGS_CMD) $(TAGS_FILE) --langmap=c++:.ino --langmap=c++:.pde $(LOCAL_SRCS) + $(CTAGS_CMD) $(TAGS_FILE) --langmap=c++:+.ino.pde $(LOCAL_SRCS) ifneq ($(words $(ARDUINO_LIBS)), 0) @$(ECHO) "Generating tags for project libraries: " $(CTAGS_CMD) $(TAGS_FILE) $(foreach lib, $(ARDUINO_LIBS),$(USER_LIB_PATH)/$(lib)/*) From 5245606f64320f1a595fa252154f55d48e5eee88 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Tue, 12 Sep 2017 14:52:31 +0000 Subject: [PATCH 02/12] Add support for ISP_PROG Atmel Ice --- Arduino.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Arduino.mk b/Arduino.mk index b964d42..3dd3fad 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -1443,7 +1443,7 @@ endif AVRDUDE_ISP_OPTS = -c $(ISP_PROG) -b $(AVRDUDE_ISP_BAUDRATE) ifndef $(ISP_PORT) - ifneq ($(strip $(ISP_PROG)),$(filter $(ISP_PROG), usbasp usbtiny gpio linuxgpio avrispmkii dragon_isp dragon_dw)) + ifneq ($(strip $(ISP_PROG)),$(filter $(ISP_PROG), atmelice_isp usbasp usbtiny gpio linuxgpio avrispmkii dragon_isp dragon_dw)) AVRDUDE_ISP_OPTS += -P $(call get_isp_port) endif else From 91604be7cc6a6b55f5890998c08856acc2dd9f0b Mon Sep 17 00:00:00 2001 From: John Whittington Date: Fri, 22 Sep 2017 14:42:24 +0000 Subject: [PATCH 03/12] WIP: CLI project makefile generator --- bin/ardmk-init | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 bin/ardmk-init diff --git a/bin/ardmk-init b/bin/ardmk-init new file mode 100644 index 0000000..225debe --- /dev/null +++ b/bin/ardmk-init @@ -0,0 +1,139 @@ +#!/usr/bin/env python + +from __future__ import print_function +import serial +import os +import argparse +from clint.textui import prompt, validators, colored, puts + +## Global Vars +VERSION = "0.1" +directory = "" +ard_template = "\n\ +#include \n\ +#include \n\ +\n\ +\n\ +void setup() {\n\ +}\n\ +\n\ +void loop() {\n\ +}\n\ +" + +## Command Parser +parser = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator. For use with Ard-Makefile') +parser.add_argument('-v', '--verbose', action='store_true', help="Print file contents during creation") +parser.add_argument('-d', '--directory', default='.', help='Directory to run generator') +args = parser.parse_args() + +directory = args.directory + +def generateMakefile(): + src_dir = "" + + puts(colored.cyan("Generating Arduino Makefile...")) + puts(colored.red("Any existing Makefile in current directory will be overwritten!!")) + # Header + fileContents = "# Generated by ard-make version " + VERSION + "\n\n" + btag = prompt.query('Board tag?', default='uno') + if not btag == 'uno': + bsub = prompt.query('Board sub micro?', default='atmega328') + f_cpu = prompt.query('Board frequency', default='16000000L') + else: + bsub = 'AUTO' + f_cpu = 'AUTO' + monitor_port = prompt.query('Arduino port?', default='AUTO') + + fileContents += checkDefine('BOARD_TAG', btag) + fileContents += checkDefine('BOARD_SUB', bsub) + fileContents += checkDefine('F_CPU', f_cpu) + fileContents += checkDefine('MONITOR_PORT', monitor_port) + + if not prompt.yn('Extended options?', default='n'): + if not prompt.yn('Define local folders?', default='n'): + src_dir = prompt.query('Sources folder (Makefile will be created here)?', default='', validators=[]) + userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', default='AUTO', validators=[]) + obj_dir = prompt.query('Output directory?', default='AUTO', validators=[]) + boards_txt = prompt.query('Boards file?', default='AUTO') + isp_prog = prompt.query('ISP programmer?', default='atmelice_isp') + isp_port = prompt.query('ISP port?', default='AUTO') + if not prompt.yn('Quiet make?', default='n'): + fileContents += "ARDUINO_QUIET = 1\n" + + fileContents += checkDefine('ISP_PROG', isp_prog) + fileContents += checkDefine('ISP_PORT', isp_port) + fileContents += checkDefine('BOARDS_TXT', boards_txt) + + # Check andd create folders + checkCreateFolder(src_dir) + checkCreateFolder(userlibs) + checkCreateFolder(obj_dir) + + # Makefile will be in src_dir so lib and bin must be relative + if src_dir: + userlibs = "../" + userlibs + obj_dir = "../" + obj_dir + + fileContents += checkDefine('USER_LIB_PATH', userlibs) + fileContents += checkDefine('OBJDIR', obj_dir) + + if not prompt.yn('Create template Arduino source?', default='n'): + sourceFilename = prompt.query('Name of project?', default='') + if src_dir: + writeTemplate(src_dir + "/" + sourceFilename) + else: + writeTemplate(sourceFilename) + fileContents += checkDefine('TARGET', sourceFilename) + + if not "ARDMK_DIR" in os.environ: + ardmk = prompt.query('Arduino Makefile path?', default='/usr/share/arduino', validators=[validators.PathValidator()]) + ardmk = "ARDMK_DIR := " + ardmk + "\n" + + + fileContents += "\ninclude $(ARDMK_DIR)/Arduino.mk" + + # Add forward slash if source directory exists + if src_dir: + writeToMakefile(fileContents, (src_dir + "/")) + else: + writeToMakefile(fileContents, "") + + return fileContents + +def writeToMakefile(fileContents, path): + makefile = open(path + "Makefile", 'w') + puts(colored.cyan("Writing Makefile...")) + if args.verbose: + puts(colored.yellow(fileContents)) + makefile.write(fileContents) + makefile.close() + +def writeTemplate(filename): + src = open((filename + ".ino"),'w') + puts(colored.cyan("Writing " + filename + ".ino...")) + if args.verbose: + puts(colored.yellow(ard_template)) + src.write("/* Project: " + filename + " */\n" + ard_template) + src.close() + +def checkCreateFolder(folder): + if folder and not folder == 'AUTO': + if not os.path.exists(folder): + puts(colored.cyan(("Creating " + folder + " folder"))) + os.makedirs(folder) + +def checkDefine(define, user): + if user and not user == 'AUTO': + return define + " = " + user + "\n" + else: + return "" + +def main(): + # Create directory if not exist + checkCreateFolder(directory) + # Change to dir so all commands are run relative + os.chdir(directory) + generateMakefile(); + +main() From 8819e761fbe45082f4a1357b80eec2b9650a5910 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Mon, 25 Sep 2017 10:45:14 +0000 Subject: [PATCH 04/12] WIP: ardmk-init more verbose about directory operating in --- bin/ardmk-init | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 bin/ardmk-init diff --git a/bin/ardmk-init b/bin/ardmk-init old mode 100644 new mode 100755 index 225debe..5976f2e --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -32,8 +32,8 @@ directory = args.directory def generateMakefile(): src_dir = "" - puts(colored.cyan("Generating Arduino Makefile...")) - puts(colored.red("Any existing Makefile in current directory will be overwritten!!")) + puts(colored.cyan("Generating Arduino Ard-Makefile project in " + os.path.abspath(directory))) + puts(colored.red("Any existing Makefile in " + os.path.abspath(directory) + " will be overwritten!!")) # Header fileContents = "# Generated by ard-make version " + VERSION + "\n\n" btag = prompt.query('Board tag?', default='uno') @@ -111,7 +111,7 @@ def writeToMakefile(fileContents, path): def writeTemplate(filename): src = open((filename + ".ino"),'w') - puts(colored.cyan("Writing " + filename + ".ino...")) + puts(colored.cyan("Writing " + os.path.abspath(filename) + ".ino...")) if args.verbose: puts(colored.yellow(ard_template)) src.write("/* Project: " + filename + " */\n" + ard_template) @@ -120,7 +120,7 @@ def writeTemplate(filename): def checkCreateFolder(folder): if folder and not folder == 'AUTO': if not os.path.exists(folder): - puts(colored.cyan(("Creating " + folder + " folder"))) + puts(colored.cyan(("Creating " + os.path.abspath(folder) + " folder"))) os.makedirs(folder) def checkDefine(define, user): From f3bb8249c128df016d1cd417e9c61f6afa3a7a2c Mon Sep 17 00:00:00 2001 From: John Whittington Date: Mon, 25 Sep 2017 15:43:13 +0000 Subject: [PATCH 05/12] ardmk-init arg parse options and made V1.0 --- bin/ardmk-init | 147 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 40 deletions(-) diff --git a/bin/ardmk-init b/bin/ardmk-init index 5976f2e..4b3b1f7 100755 --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -7,8 +7,8 @@ import argparse from clint.textui import prompt, validators, colored, puts ## Global Vars -VERSION = "0.1" -directory = "" +VERSION = "1.0" +directory = os.getcwd() ard_template = "\n\ #include \n\ #include \n\ @@ -22,48 +22,100 @@ void loop() {\n\ " ## Command Parser -parser = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator. For use with Ard-Makefile') -parser.add_argument('-v', '--verbose', action='store_true', help="Print file contents during creation") -parser.add_argument('-d', '--directory', default='.', help='Directory to run generator') +parser = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator. For use with Ard-Makefile: https://github.com/sudar/Arduino-Makefile. Script created by John Whittington https://github.com/tuna-f1sh 2017\n\nVersion: ' + VERSION, usage='"ardmk-init -b uno -quiet -project" Automonously create boiler plate Arduino Uno project in current working directory with same name. See --help for more.') +parser.add_argument('-v', '--verbose', action='store_true', help="print file contents during creation") +parser.add_argument('-d', '--directory', default=directory, help='directory to run generator') +parser.add_argument('-b', '--board', default='uno', help='board tag') +parser.add_argument('-u', '--micro', default='AUTO', help='microcontroller on board') +parser.add_argument('-f', '--freq', default='AUTO', help='mlock frequency') +parser.add_argument('-p', '--port', default='AUTO', help='monitor port') +parser.add_argument('-n', '--name', default=os.path.basename(directory), help='project name') +parser.add_argument('-q', '--quiet', action='store_true', help='run quiet without user prompts') +parser.add_argument('-P', '--project', action='store_true', help='create boilerplate project with src, lib and bin folder structure') +parser.add_argument('-t', '--template', action='store_true', help='create bare minimum Arduino source file') args = parser.parse_args() directory = args.directory def generateMakefile(): - src_dir = "" - - puts(colored.cyan("Generating Arduino Ard-Makefile project in " + os.path.abspath(directory))) - puts(colored.red("Any existing Makefile in " + os.path.abspath(directory) + " will be overwritten!!")) # Header fileContents = "# Generated by ard-make version " + VERSION + "\n\n" - btag = prompt.query('Board tag?', default='uno') - if not btag == 'uno': - bsub = prompt.query('Board sub micro?', default='atmega328') - f_cpu = prompt.query('Board frequency', default='16000000L') + + # Basic + if not args.quiet: + puts(colored.cyan("Generating Arduino Ard-Makefile project in " + os.path.abspath(directory))) + btag = prompt.query('Board tag?', default='uno') + if not btag == 'uno': + bsub = prompt.query('Board sub micro?', default='atmega328') + f_cpu = prompt.query('Board frequency', default='16000000L') + else: + bsub = 'AUTO' + f_cpu = 'AUTO' + monitor_port = prompt.query('Arduino port?', default='AUTO') else: - bsub = 'AUTO' - f_cpu = 'AUTO' - monitor_port = prompt.query('Arduino port?', default='AUTO') + btag = args.board + bsub = args.micro + f_cpu = args.freq + monitor_port = args.port fileContents += checkDefine('BOARD_TAG', btag) fileContents += checkDefine('BOARD_SUB', bsub) fileContents += checkDefine('F_CPU', f_cpu) fileContents += checkDefine('MONITOR_PORT', monitor_port) - if not prompt.yn('Extended options?', default='n'): - if not prompt.yn('Define local folders?', default='n'): - src_dir = prompt.query('Sources folder (Makefile will be created here)?', default='', validators=[]) - userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', default='AUTO', validators=[]) - obj_dir = prompt.query('Output directory?', default='AUTO', validators=[]) - boards_txt = prompt.query('Boards file?', default='AUTO') - isp_prog = prompt.query('ISP programmer?', default='atmelice_isp') - isp_port = prompt.query('ISP port?', default='AUTO') - if not prompt.yn('Quiet make?', default='n'): - fileContents += "ARDUINO_QUIET = 1\n" + # Extended + if not args.quiet: + if not prompt.yn('Extended options?', default='n'): + if not prompt.yn('Define local folders?', default='n'): + src_dir = prompt.query('Sources folder (Makefile will be created here)?', default='', validators=[]) + userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', default='AUTO', validators=[]) + obj_dir = prompt.query('Output directory?', default='AUTO', validators=[]) + else: + src_dir = '' + userlibs = 'AUTO' + obj_dir = 'AUTO' + boards_txt = prompt.query('Boards file?', default='AUTO') + isp_prog = prompt.query('ISP programmer?', default='atmelice_isp') + isp_port = prompt.query('ISP port?', default='AUTO') + if not prompt.yn('Quiet make?', default='n'): + fileContents += "ARDUINO_QUIET = 1\n" - fileContents += checkDefine('ISP_PROG', isp_prog) - fileContents += checkDefine('ISP_PORT', isp_port) - fileContents += checkDefine('BOARDS_TXT', boards_txt) + fileContents += checkDefine('ISP_PROG', isp_prog) + fileContents += checkDefine('ISP_PORT', isp_port) + fileContents += checkDefine('BOARDS_TXT', boards_txt) + + # Check andd create folders + checkCreateFolder(src_dir) + checkCreateFolder(userlibs) + checkCreateFolder(obj_dir) + + # Makefile will be in src_dir so lib and bin must be relative + if src_dir: + userlibs = "../" + userlibs + obj_dir = "../" + obj_dir + + fileContents += checkDefine('USER_LIB_PATH', userlibs) + fileContents += checkDefine('OBJDIR', obj_dir) + else: + src_dir = '' + + if args.template or not prompt.yn('Create template Arduino source?', default='n'): + sourceFilename = prompt.query('Name of project?', default=os.path.basename(os.getcwd())) + if src_dir: + writeTemplate(src_dir + "/" + sourceFilename) + else: + writeTemplate(sourceFilename) + fileContents += checkDefine('TARGET', sourceFilename) + + else: + if args.project: + src_dir = 'src' + userlibs = 'lib' + obj_dir = 'bin' + else: + src_dir = '' + userlibs = 'AUTO' + obj_dir = 'AUTO' # Check andd create folders checkCreateFolder(src_dir) @@ -78,18 +130,19 @@ def generateMakefile(): fileContents += checkDefine('USER_LIB_PATH', userlibs) fileContents += checkDefine('OBJDIR', obj_dir) - if not prompt.yn('Create template Arduino source?', default='n'): - sourceFilename = prompt.query('Name of project?', default='') - if src_dir: - writeTemplate(src_dir + "/" + sourceFilename) - else: - writeTemplate(sourceFilename) - fileContents += checkDefine('TARGET', sourceFilename) + if args.project or args.template: + if src_dir: + writeTemplate(src_dir + "/" + args.name) + else: + writeTemplate(args.name) + fileContents += checkDefine('TARGET', args.name) if not "ARDMK_DIR" in os.environ: - ardmk = prompt.query('Arduino Makefile path?', default='/usr/share/arduino', validators=[validators.PathValidator()]) - ardmk = "ARDMK_DIR := " + ardmk + "\n" - + if args.quiet: + puts(colored.magenta('Warning: ARDMK_DIR environment variable not defined. Must be defined for Makefile to work')) + else: + ardmk = prompt.query('Arduino Makefile path?', default='/usr/share/arduino', validators=[validators.PathValidator()]) + ardmk = "ARDMK_DIR := " + ardmk + "\n" fileContents += "\ninclude $(ARDMK_DIR)/Arduino.mk" @@ -110,8 +163,15 @@ def writeToMakefile(fileContents, path): makefile.close() def writeTemplate(filename): - src = open((filename + ".ino"),'w') puts(colored.cyan("Writing " + os.path.abspath(filename) + ".ino...")) + if os.path.isfile(filename + '.ino'): + if args.quiet: + puts(colored.red(filename + '.ino' + ' already exists! Stopping.')) + return + puts(colored.red(filename + '.ino' + ' already exists! Overwrite?')) + if prompt.yn('Continue?', default='n'): + return + src = open((filename + ".ino"),'w') if args.verbose: puts(colored.yellow(ard_template)) src.write("/* Project: " + filename + " */\n" + ard_template) @@ -134,6 +194,13 @@ def main(): checkCreateFolder(directory) # Change to dir so all commands are run relative os.chdir(directory) + if os.path.isfile('Makefile'): + if args.quiet: + puts(colored.red('Makefile in ' + os.path.abspath(directory) + ' already exists! Stopping.')) + return + puts(colored.red('Makefile in ' + os.path.abspath(directory) + ' already exists! Overwrite?')) + if prompt.yn('Continue?', default='n'): + return generateMakefile(); main() From a165a3bf26525fed69a1255b3fdf5e51f9003aa0 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Thu, 28 Sep 2017 13:26:29 +0100 Subject: [PATCH 06/12] ardmk-init usage added to README and HISTORY update --- HISTORY.md | 4 +++- README.md | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 6fa2606..df178dd 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -11,8 +11,10 @@ I tried to give credit whenever possible. If I have missed anyone, kindly add it - Tweak: Move non-standard-related items from CxxFLAGS_STD to CxxFLAGS (issue #523) (https://github.com/sej7278) - Tweak: Update Windows usage documentation and allow non-relative paths (issue #519) (https://github.com/tuna-f1sh) - Tweak: Support Cygwin Unix Python and Windows installation on Windows to pass correct port binding. (https://github.com/tuna-f1sh) -- New: Added -fdiagnostics-color to *STD flags (https://github.com/sej7278) +- New: Added -fdiagnostics-color to \*STD flags (https://github.com/sej7278) - New: Add generation of tags file using ctags, which automatically includes project libs and Arduino core. (https://github.com/tuna-f1sh) +- New: Add template Makefile and project boilerplate initialise script, `ardmk-init`. (https://github.com/tuna-f1sh) +- New: Support atmelice_isp JTAG tool as ISP programmer. (https://github.com/tuna-f1sh) ### 1.6.0 (2017-07-11) - Fix: Allowed for SparkFun's weird usb pid/vid submenu shenanigans (issue #499). (https://github.com/sej7278) diff --git a/README.md b/README.md index 972b03d..953d067 100644 --- a/README.md +++ b/README.md @@ -428,6 +428,20 @@ all of the examples. The bootstrap script is primarily intended for use by a continuous integration server, specifically Travis CI. It is not intended for normal users. +## Makefile Generator and Project Initialisation + +`ardmk-init` within the bin/ folder is a utility Python script to create a +Arduino-mk Makefile for a project and also has option to create a traditional *tree* +organization (src, lib, bin). It can be used as with commanline arguments or +prompted - see examples below (append `$ARDMK_DIR/bin/` to command if not on path): + +* Run prompted within current working directory: `ardmk-init` +* Create Arduino Uno Makefile (useful within a library example): `ardmk-init -qb uno` +* Create boilerplate Arduino Uno project in current working directory of same + name: `ardmk-init -b uno --quiet --project` +* Create Arduino-mk nano Makefile in current working directory with template .ino: `ardmk-init -b nano -u atmega328 -qtn my-project` +* See `ardmk-init --help` for more. + ### Bare-Arduino–Project If you are planning on using this makefile in a larger/professional project, you might want to take a look at the [Bare-Arduino–Project](https://github.com/WeAreLeka/Bare-Arduino-Project) framework. From c2d17c825a7b9e20c8ad76d5983007db20fa5e0b Mon Sep 17 00:00:00 2001 From: John Whittington Date: Mon, 2 Oct 2017 15:26:02 +0100 Subject: [PATCH 07/12] ardmk-init linted using pylint --- bin/ardmk-init | 228 ++++++++++++++++++++++++++++++------------------- 1 file changed, 138 insertions(+), 90 deletions(-) diff --git a/bin/ardmk-init b/bin/ardmk-init index 4b3b1f7..ec1f3b8 100755 --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -1,15 +1,30 @@ #!/usr/bin/env python +""" +Arduino-mk Makefile and project initialiser + +This script can be used in it's basic form create a project specific Makefile +for use with Arduino-mk. Addionally, it can be used to create a template +Arduino source file and a traditional boilerplate project file structure. + +Example: + * Run prompted within current working directory: `ardmk-init` + * Create Arduino Uno Makefile (useful within a library example): `ardmk-init -qb uno` + * Create boilerplate Arduino Uno project in current working directory of same + name: `ardmk-init -b uno --quiet --project` + * Create Arduino-mk nano Makefile in current working directory with template .ino: + `ardmk-init -b nano -u atmega328 -qtn my-project` + +See `armk-init --help` for CLI arguments +""" from __future__ import print_function -import serial import os import argparse from clint.textui import prompt, validators, colored, puts ## Global Vars VERSION = "1.0" -directory = os.getcwd() -ard_template = "\n\ +ARD_TEMPLATE = "\n\ #include \n\ #include \n\ \n\ @@ -22,30 +37,38 @@ void loop() {\n\ " ## Command Parser -parser = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator. For use with Ard-Makefile: https://github.com/sudar/Arduino-Makefile. Script created by John Whittington https://github.com/tuna-f1sh 2017\n\nVersion: ' + VERSION, usage='"ardmk-init -b uno -quiet -project" Automonously create boiler plate Arduino Uno project in current working directory with same name. See --help for more.') -parser.add_argument('-v', '--verbose', action='store_true', help="print file contents during creation") -parser.add_argument('-d', '--directory', default=directory, help='directory to run generator') -parser.add_argument('-b', '--board', default='uno', help='board tag') -parser.add_argument('-u', '--micro', default='AUTO', help='microcontroller on board') -parser.add_argument('-f', '--freq', default='AUTO', help='mlock frequency') -parser.add_argument('-p', '--port', default='AUTO', help='monitor port') -parser.add_argument('-n', '--name', default=os.path.basename(directory), help='project name') -parser.add_argument('-q', '--quiet', action='store_true', help='run quiet without user prompts') -parser.add_argument('-P', '--project', action='store_true', help='create boilerplate project with src, lib and bin folder structure') -parser.add_argument('-t', '--template', action='store_true', help='create bare minimum Arduino source file') -args = parser.parse_args() +PARSER = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator.\ + For use with Ard-Makefile: https://github.com/sudar/Arduino-Makefile.\ + Script created by John Whittington https://github.com/tuna-f1sh 2017\ + \n\nVersion: ' + VERSION, usage='ardmk-init # prompted CLI, see --help for more.') +PARSER.add_argument('-v', '--verbose', action='store_true', + help="print file contents during creation") +PARSER.add_argument('-d', '--directory', default=os.getcwd(), help='directory to run generator') +PARSER.add_argument('-b', '--board', default='uno', help='board tag') +PARSER.add_argument('-u', '--micro', default='AUTO', help='microcontroller on board') +PARSER.add_argument('-f', '--freq', default='AUTO', help='mlock frequency') +PARSER.add_argument('-p', '--port', default='AUTO', help='monitor port') +PARSER.add_argument('-n', '--name', default=os.path.basename(os.getcwd()), help='project name') +PARSER.add_argument('-q', '--quiet', action='store_true', help='run quiet without user prompts') +PARSER.add_argument('-P', '--project', action='store_true', + help='create boilerplate project with src, lib and bin folder structure') +PARSER.add_argument('-t', '--template', action='store_true', + help='create bare minimum Arduino source file') +ARGS = PARSER.parse_args() -directory = args.directory - -def generateMakefile(): +def generate_makefile(): + """ + Generate the Makefile content using prompts or parsed arguments + """ # Header - fileContents = "# Generated by ard-make version " + VERSION + "\n\n" + file_content = "# Generated by ard-make version " + VERSION + "\n\n" # Basic - if not args.quiet: - puts(colored.cyan("Generating Arduino Ard-Makefile project in " + os.path.abspath(directory))) + if not ARGS.quiet: + puts(colored.cyan("Generating Arduino Ard-Makefile project in " + + os.path.abspath(ARGS.directory))) btag = prompt.query('Board tag?', default='uno') - if not btag == 'uno': + if btag != 'uno': bsub = prompt.query('Board sub micro?', default='atmega328') f_cpu = prompt.query('Board frequency', default='16000000L') else: @@ -53,22 +76,24 @@ def generateMakefile(): f_cpu = 'AUTO' monitor_port = prompt.query('Arduino port?', default='AUTO') else: - btag = args.board - bsub = args.micro - f_cpu = args.freq - monitor_port = args.port + btag = ARGS.board + bsub = ARGS.micro + f_cpu = ARGS.freq + monitor_port = ARGS.port - fileContents += checkDefine('BOARD_TAG', btag) - fileContents += checkDefine('BOARD_SUB', bsub) - fileContents += checkDefine('F_CPU', f_cpu) - fileContents += checkDefine('MONITOR_PORT', monitor_port) + file_content += check_define('BOARD_TAG', btag) + file_content += check_define('BOARD_SUB', bsub) + file_content += check_define('F_CPU', f_cpu) + file_content += check_define('MONITOR_PORT', monitor_port) # Extended - if not args.quiet: + if not ARGS.quiet: if not prompt.yn('Extended options?', default='n'): if not prompt.yn('Define local folders?', default='n'): - src_dir = prompt.query('Sources folder (Makefile will be created here)?', default='', validators=[]) - userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', default='AUTO', validators=[]) + src_dir = prompt.query('Sources folder (Makefile will be created here)?',\ + default='', validators=[]) + userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', + default='AUTO', validators=[]) obj_dir = prompt.query('Output directory?', default='AUTO', validators=[]) else: src_dir = '' @@ -78,37 +103,38 @@ def generateMakefile(): isp_prog = prompt.query('ISP programmer?', default='atmelice_isp') isp_port = prompt.query('ISP port?', default='AUTO') if not prompt.yn('Quiet make?', default='n'): - fileContents += "ARDUINO_QUIET = 1\n" + file_content += "ARDUINO_QUIET = 1\n" - fileContents += checkDefine('ISP_PROG', isp_prog) - fileContents += checkDefine('ISP_PORT', isp_port) - fileContents += checkDefine('BOARDS_TXT', boards_txt) + file_content += check_define('ISP_PROG', isp_prog) + file_content += check_define('ISP_PORT', isp_port) + file_content += check_define('BOARDS_TXT', boards_txt) # Check andd create folders - checkCreateFolder(src_dir) - checkCreateFolder(userlibs) - checkCreateFolder(obj_dir) + check_create_folder(src_dir) + check_create_folder(userlibs) + check_create_folder(obj_dir) # Makefile will be in src_dir so lib and bin must be relative if src_dir: userlibs = "../" + userlibs obj_dir = "../" + obj_dir - fileContents += checkDefine('USER_LIB_PATH', userlibs) - fileContents += checkDefine('OBJDIR', obj_dir) + file_content += check_define('USER_LIB_PATH', userlibs) + file_content += check_define('OBJDIR', obj_dir) else: src_dir = '' - if args.template or not prompt.yn('Create template Arduino source?', default='n'): - sourceFilename = prompt.query('Name of project?', default=os.path.basename(os.getcwd())) + if ARGS.template or not prompt.yn('Create template Arduino source?', default='n'): + source_filename = prompt.query('Name of project?', + default=os.path.basename(os.getcwd())) if src_dir: - writeTemplate(src_dir + "/" + sourceFilename) + write_template(src_dir + "/" + source_filename) else: - writeTemplate(sourceFilename) - fileContents += checkDefine('TARGET', sourceFilename) + write_template(source_filename) + file_content += check_define('TARGET', source_filename) else: - if args.project: + if ARGS.project: src_dir = 'src' userlibs = 'lib' obj_dir = 'bin' @@ -118,89 +144,111 @@ def generateMakefile(): obj_dir = 'AUTO' # Check andd create folders - checkCreateFolder(src_dir) - checkCreateFolder(userlibs) - checkCreateFolder(obj_dir) + check_create_folder(src_dir) + check_create_folder(userlibs) + check_create_folder(obj_dir) # Makefile will be in src_dir so lib and bin must be relative if src_dir: userlibs = "../" + userlibs obj_dir = "../" + obj_dir - fileContents += checkDefine('USER_LIB_PATH', userlibs) - fileContents += checkDefine('OBJDIR', obj_dir) + file_content += check_define('USER_LIB_PATH', userlibs) + file_content += check_define('OBJDIR', obj_dir) - if args.project or args.template: + if ARGS.project or ARGS.template: if src_dir: - writeTemplate(src_dir + "/" + args.name) + write_template(src_dir + "/" + ARGS.name) else: - writeTemplate(args.name) - fileContents += checkDefine('TARGET', args.name) + write_template(ARGS.name) + file_content += check_define('TARGET', ARGS.name) if not "ARDMK_DIR" in os.environ: - if args.quiet: - puts(colored.magenta('Warning: ARDMK_DIR environment variable not defined. Must be defined for Makefile to work')) + if ARGS.quiet: + puts(colored.magenta('Warning: ARDMK_DIR environment variable not defined. \ + Must be defined for Makefile to work')) else: - ardmk = prompt.query('Arduino Makefile path?', default='/usr/share/arduino', validators=[validators.PathValidator()]) + ardmk = prompt.query('Arduino Makefile path?', + default='/usr/share/arduino', + validators=[validators.PathValidator()]) ardmk = "ARDMK_DIR := " + ardmk + "\n" - fileContents += "\ninclude $(ARDMK_DIR)/Arduino.mk" + file_content += "\ninclude $(ARDMK_DIR)/Arduino.mk" # Add forward slash if source directory exists if src_dir: - writeToMakefile(fileContents, (src_dir + "/")) + write_to_makefile(file_content, (src_dir + "/")) else: - writeToMakefile(fileContents, "") + write_to_makefile(file_content, "") - return fileContents + return file_content -def writeToMakefile(fileContents, path): +def write_to_makefile(file_content, path): + """ + Write the Makefile file + """ makefile = open(path + "Makefile", 'w') puts(colored.cyan("Writing Makefile...")) - if args.verbose: - puts(colored.yellow(fileContents)) - makefile.write(fileContents) + if ARGS.verbose: + puts(colored.yellow(file_content)) + makefile.write(file_content) makefile.close() -def writeTemplate(filename): +def write_template(filename): + """ + Write template Arduino .ino source + """ puts(colored.cyan("Writing " + os.path.abspath(filename) + ".ino...")) if os.path.isfile(filename + '.ino'): - if args.quiet: + if ARGS.quiet: puts(colored.red(filename + '.ino' + ' already exists! Stopping.')) return puts(colored.red(filename + '.ino' + ' already exists! Overwrite?')) if prompt.yn('Continue?', default='n'): return - src = open((filename + ".ino"),'w') - if args.verbose: - puts(colored.yellow(ard_template)) - src.write("/* Project: " + filename + " */\n" + ard_template) + src = open((filename + ".ino"), 'w') + if ARGS.verbose: + puts(colored.yellow(ARD_TEMPLATE)) + src.write("/* Project: " + filename + " */\n" + ARD_TEMPLATE) src.close() -def checkCreateFolder(folder): +def check_create_folder(folder): + """ + Check if folder exists and make it if it doesn't and hasn't been set to AUTO + """ if folder and not folder == 'AUTO': if not os.path.exists(folder): puts(colored.cyan(("Creating " + os.path.abspath(folder) + " folder"))) os.makedirs(folder) -def checkDefine(define, user): +def check_define(define, user): + """ + Check whether user has set define and return Makefile formatted string if they have + """ + # Return is empty unless user has passed value + string = "" + + # Set define only if not empty or set to AUTO if user and not user == 'AUTO': - return define + " = " + user + "\n" - else: - return "" + string = define + " = " + user + "\n" -def main(): + return string + +if __name__ == '__main__': # Create directory if not exist - checkCreateFolder(directory) + check_create_folder(ARGS.directory) # Change to dir so all commands are run relative - os.chdir(directory) + os.chdir(ARGS.directory) if os.path.isfile('Makefile'): - if args.quiet: - puts(colored.red('Makefile in ' + os.path.abspath(directory) + ' already exists! Stopping.')) - return - puts(colored.red('Makefile in ' + os.path.abspath(directory) + ' already exists! Overwrite?')) - if prompt.yn('Continue?', default='n'): - return - generateMakefile(); + if ARGS.quiet: + puts(colored.red('Makefile in ' + os.path.abspath(ARGS.directory) + + ' already exists! Stopping.')) + quit() -main() + # Confirm with user if not quiet mode + puts(colored.red('Makefile in ' + os.path.abspath(ARGS.directory) + + ' already exists! Overwrite?')) + if prompt.yn('Continue?', default='n'): + quit() + # Run it + generate_makefile() From b8f5eaa816daeaa49340e989376c8d5d08325047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Tue, 26 Sep 2017 17:36:38 +0200 Subject: [PATCH 08/12] Recognize serial monitors with full path in MONITOR_CMD When assembling the command line for the various supported serial monitors, MONITOR_CMD must match the name of one of the supported commands to be recognized. Serial monitors given with leading path components are not recognized, and a command like make MONITOR_CMD=~/src/picocom/picocom monitor errors out as the fallback monitor command is executed instead of the picocom-specific one. However, sometimes it's necessary to specify a supported serial monitor with its full path, because e.g. the user wants to tests a freshly compiled version before installing it. Sure, the user could just run the serial monitor directly, but that's cumbersome because he has to pay attention to use the right baud rate and USB port. So strip all leading path components, if present, from MONITOR_CMD using the 'nondir' make function before checking whether it's one of the supported serial monitors. This way commands like the above would just work. While at it, remove the single quotes around 'putty': they are both unnecessary and inconsistent with similar constructs throughout Arduino.mk. --- Arduino.mk | 6 +++--- HISTORY.md | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Arduino.mk b/Arduino.mk index 3dd3fad..26d1b20 100644 --- a/Arduino.mk +++ b/Arduino.mk @@ -1566,15 +1566,15 @@ show_submenu: @$(CAT) $(BOARDS_TXT) | grep -E '[a-zA-Z0-9_\-]+.menu.(cpu|chip).[a-zA-Z0-9_\-]+=' | sort -uf | sed 's/.menu.\(cpu\|chip\)./:/' | sed 's/=/:/' | column -s: -t monitor: -ifeq ($(MONITOR_CMD), 'putty') +ifeq ($(notdir $(MONITOR_CMD)), putty) ifneq ($(strip $(MONITOR_PARAMS)),) $(MONITOR_CMD) -serial -sercfg $(MONITOR_BAUDRATE),$(MONITOR_PARAMS) $(call get_monitor_port) else $(MONITOR_CMD) -serial -sercfg $(MONITOR_BAUDRATE) $(call get_monitor_port) endif -else ifeq ($(MONITOR_CMD), picocom) +else ifeq ($(notdir $(MONITOR_CMD)), picocom) $(MONITOR_CMD) -b $(MONITOR_BAUDRATE) $(MONITOR_PARAMS) $(call get_monitor_port) -else ifeq ($(MONITOR_CMD), cu) +else ifeq ($(notdir $(MONITOR_CMD)), cu) $(MONITOR_CMD) -l $(call get_monitor_port) -s $(MONITOR_BAUDRATE) else $(MONITOR_CMD) $(call get_monitor_port) $(MONITOR_BAUDRATE) diff --git a/HISTORY.md b/HISTORY.md index df178dd..b125408 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,7 @@ I tried to give credit whenever possible. If I have missed anyone, kindly add it ### In Development - Fix: Add -fno-devirtualize flag to workaround g++ segfault bug (issue #486). (https://github.com/sej7278) - Fix: Quote the prefix tag in the space_pad_to function +- Fix: recognize serial monitors with full path in MONITOR_CMD - Tweak: Set ARDMK_VERSION to 1.6 (https://github.com/sej7278) - Tweak: Move non-standard-related items from CxxFLAGS_STD to CxxFLAGS (issue #523) (https://github.com/sej7278) - Tweak: Update Windows usage documentation and allow non-relative paths (issue #519) (https://github.com/tuna-f1sh) From 55c149fb0352a56b57fce98c706a0a23f743a66b Mon Sep 17 00:00:00 2001 From: John Whittington Date: Fri, 6 Oct 2017 10:32:17 +0100 Subject: [PATCH 09/12] Add ardmk-init manpage and correct typos --- ardmk-init.1 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ bin/ardmk-init | 4 ++-- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 ardmk-init.1 diff --git a/ardmk-init.1 b/ardmk-init.1 new file mode 100644 index 0000000..87f0382 --- /dev/null +++ b/ardmk-init.1 @@ -0,0 +1,60 @@ +.TH ARDMK-INIT "1" "Oct 2017" "ardmk-init" "Arduino Makefile Generator" + +.SH NAME +ardmk-init - Generate Arduino Makefile environments + +.SH SYNOPSIS +.B ardmk-init +[OPTION]... + +.SH OPTIONS +.B \-v, \-\-verbose +Print file contents during creation. + +.B \-d, \-\-directory +Directory to run generator. + +.B \-b, \-\-board +Board tag. + +.B \-u, \-\-micro +Microcontroller on board. + +.B \-f, \-\-freq +Clock frequency. + +.B \-p, \-\-port +Monitor port. + +.B \-n, \-\-name +Project name. + +.B \-q, \-\-quiet +Run quiet without user prompts. + +.B \-p, \-\-project +Create boilerplate project with src, lib and bin folder structure. + +.B \-t, \-\-template +Create bare minimum Arduino source file. + +.SH DESCRIPTION +Creates a Makefile and project tree structure from templates. + +.SH EXAMPLE +ardmk-init -qb uno # create Arduino uno Makefile quietly +.PP +ardmk-init # run with user prompts +.PP +ardmk-init --board uno --project --template --name my-project --quiet # create Arduino uno project and template with name "my-project" + +.SH BUGS +Problems may reported on the github project page at: +.PP +https://github.com/sudar/Arduino-Makefile + +.SH AUTHOR +John Whittington, git@jbrengineering.co.uk + +.SH LICENSE +This is under MIT license. diff --git a/bin/ardmk-init b/bin/ardmk-init index ec1f3b8..bf932d5 100755 --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -2,7 +2,7 @@ """ Arduino-mk Makefile and project initialiser -This script can be used in it's basic form create a project specific Makefile +This script can be used in its basic form create a project specific Makefile for use with Arduino-mk. Addionally, it can be used to create a template Arduino source file and a traditional boilerplate project file structure. @@ -46,7 +46,7 @@ PARSER.add_argument('-v', '--verbose', action='store_true', PARSER.add_argument('-d', '--directory', default=os.getcwd(), help='directory to run generator') PARSER.add_argument('-b', '--board', default='uno', help='board tag') PARSER.add_argument('-u', '--micro', default='AUTO', help='microcontroller on board') -PARSER.add_argument('-f', '--freq', default='AUTO', help='mlock frequency') +PARSER.add_argument('-f', '--freq', default='AUTO', help='clock frequency') PARSER.add_argument('-p', '--port', default='AUTO', help='monitor port') PARSER.add_argument('-n', '--name', default=os.path.basename(os.getcwd()), help='project name') PARSER.add_argument('-q', '--quiet', action='store_true', help='run quiet without user prompts') From 2a4c2660be99e0b27c4faed9980d5ab0b96ee2e2 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Thu, 12 Oct 2017 09:25:56 +0100 Subject: [PATCH 10/12] Run ardmk-init without dependancy if running quiet --- bin/ardmk-init | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/bin/ardmk-init b/bin/ardmk-init index bf932d5..461e9ab 100755 --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -20,7 +20,6 @@ See `armk-init --help` for CLI arguments from __future__ import print_function import os import argparse -from clint.textui import prompt, validators, colored, puts ## Global Vars VERSION = "1.0" @@ -56,6 +55,14 @@ PARSER.add_argument('-t', '--template', action='store_true', help='create bare minimum Arduino source file') ARGS = PARSER.parse_args() +try: + from clint.textui import prompt, validators +except ImportError: + if not ARGS.quiet: + print("Python module 'clint' is required for running prompted. Install the module or run with arguments only using --quiet") + quit() + + def generate_makefile(): """ Generate the Makefile content using prompts or parsed arguments @@ -65,8 +72,8 @@ def generate_makefile(): # Basic if not ARGS.quiet: - puts(colored.cyan("Generating Arduino Ard-Makefile project in " - + os.path.abspath(ARGS.directory))) + print("Generating Arduino Ard-Makefile project in " + + os.path.abspath(ARGS.directory)) btag = prompt.query('Board tag?', default='uno') if btag != 'uno': bsub = prompt.query('Board sub micro?', default='atmega328') @@ -188,9 +195,9 @@ def write_to_makefile(file_content, path): Write the Makefile file """ makefile = open(path + "Makefile", 'w') - puts(colored.cyan("Writing Makefile...")) + print("Writing Makefile...") if ARGS.verbose: - puts(colored.yellow(file_content)) + print(file_content) makefile.write(file_content) makefile.close() @@ -198,17 +205,17 @@ def write_template(filename): """ Write template Arduino .ino source """ - puts(colored.cyan("Writing " + os.path.abspath(filename) + ".ino...")) + print("Writing " + os.path.abspath(filename) + ".ino...") if os.path.isfile(filename + '.ino'): if ARGS.quiet: - puts(colored.red(filename + '.ino' + ' already exists! Stopping.')) + print(filename + '.ino' + ' already exists! Stopping.') return - puts(colored.red(filename + '.ino' + ' already exists! Overwrite?')) + print(filename + '.ino' + ' already exists! Overwrite?') if prompt.yn('Continue?', default='n'): return src = open((filename + ".ino"), 'w') if ARGS.verbose: - puts(colored.yellow(ARD_TEMPLATE)) + print(ARD_TEMPLATE) src.write("/* Project: " + filename + " */\n" + ARD_TEMPLATE) src.close() @@ -218,7 +225,7 @@ def check_create_folder(folder): """ if folder and not folder == 'AUTO': if not os.path.exists(folder): - puts(colored.cyan(("Creating " + os.path.abspath(folder) + " folder"))) + print("Creating " + os.path.abspath(folder) + " folder") os.makedirs(folder) def check_define(define, user): @@ -241,13 +248,13 @@ if __name__ == '__main__': os.chdir(ARGS.directory) if os.path.isfile('Makefile'): if ARGS.quiet: - puts(colored.red('Makefile in ' + os.path.abspath(ARGS.directory) - + ' already exists! Stopping.')) + print('Makefile in ' + os.path.abspath(ARGS.directory) + + ' already exists! Stopping.') quit() # Confirm with user if not quiet mode - puts(colored.red('Makefile in ' + os.path.abspath(ARGS.directory) - + ' already exists! Overwrite?')) + print('Makefile in ' + os.path.abspath(ARGS.directory) + + ' already exists! Overwrite?') if prompt.yn('Continue?', default='n'): quit() # Run it From 78d11c66782dde22b5eeca00867aeebb3ff0f1bb Mon Sep 17 00:00:00 2001 From: John Whittington Date: Fri, 13 Oct 2017 15:41:56 +0100 Subject: [PATCH 11/12] Update Fedora spec file --- packaging/fedora/arduino-mk.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packaging/fedora/arduino-mk.spec b/packaging/fedora/arduino-mk.spec index 61bf317..b1f07f1 100644 --- a/packaging/fedora/arduino-mk.spec +++ b/packaging/fedora/arduino-mk.spec @@ -39,6 +39,8 @@ install -m 755 bin/ard-reset-arduino %{buildroot}/%{_bindir}/ard-reset-arduino install -m 644 ard-reset-arduino.1 %{buildroot}/%{_mandir}/man1 install -m 755 bin/robotis-loader %{buildroot}/%{_bindir}/robotis-loader install -m 644 robotis-loader.1 %{buildroot}/%{_mandir}/man1 +install -m 755 bin/ardmk-init %{buildroot}/%{_bindir}/ardmk-init +install -m 644 ardmk-init.1 %{buildroot}/%{_mandir}/man1 %clean rm -rf %{buildroot} @@ -49,6 +51,8 @@ rm -rf %{buildroot} %{_mandir}/man1/ard-reset-arduino.1* %{_bindir}/robotis-loader %{_mandir}/man1/robotis-loader.1* +%{_bindir}/ardmk-init +%{_mandir}/man1/ardmk-init.1* %{_datadir}/arduino/*.mk %{_datadir}/arduino/arduino-mk-vars.md %doc %{_docdir}/%{name}/licence.txt @@ -56,6 +60,8 @@ rm -rf %{buildroot} %{_docdir}/%{name}/examples %changelog +* Thu Oct 05 2017 Simon John +- Added ardmk-init binary and manpage * Tue Jul 11 2017 Karl Semich - Added robotis-loader binary and manpage * Sat Apr 12 2014 Simon John From d874c59103fc9619df906c0f967bcfa539325592 Mon Sep 17 00:00:00 2001 From: John Whittington Date: Tue, 7 Nov 2017 16:54:34 +0000 Subject: [PATCH 12/12] ardmk-init runs without prompt by default, cli arg added to avoid clint dependency --- ardmk-init.1 | 12 +++++----- bin/ardmk-init | 59 ++++++++++++++++++++++++++++++-------------------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/ardmk-init.1 b/ardmk-init.1 index 87f0382..bb83fd2 100644 --- a/ardmk-init.1 +++ b/ardmk-init.1 @@ -1,4 +1,4 @@ -.TH ARDMK-INIT "1" "Oct 2017" "ardmk-init" "Arduino Makefile Generator" +.TH ARDMK-INIT "1" "Nov 2017" "ardmk-init" "Arduino Makefile Generator" .SH NAME ardmk-init - Generate Arduino Makefile environments @@ -29,8 +29,8 @@ Monitor port. .B \-n, \-\-name Project name. -.B \-q, \-\-quiet -Run quiet without user prompts. +.B \-\-cli +Run with user prompts rather than arguments. .B \-p, \-\-project Create boilerplate project with src, lib and bin folder structure. @@ -42,11 +42,11 @@ Create bare minimum Arduino source file. Creates a Makefile and project tree structure from templates. .SH EXAMPLE -ardmk-init -qb uno # create Arduino uno Makefile quietly +ardmk-init -b uno # create Arduino uno Makefile .PP -ardmk-init # run with user prompts +ardmk-init --cli # run with user prompts .PP -ardmk-init --board uno --project --template --name my-project --quiet # create Arduino uno project and template with name "my-project" +ardmk-init --board uno --project --template --name my-project # create Arduino uno project and template with name "my-project" .SH BUGS Problems may reported on the github project page at: diff --git a/bin/ardmk-init b/bin/ardmk-init index 461e9ab..1a01cd3 100755 --- a/bin/ardmk-init +++ b/bin/ardmk-init @@ -7,12 +7,12 @@ for use with Arduino-mk. Addionally, it can be used to create a template Arduino source file and a traditional boilerplate project file structure. Example: - * Run prompted within current working directory: `ardmk-init` - * Create Arduino Uno Makefile (useful within a library example): `ardmk-init -qb uno` + * Run prompted within current working directory (requires Clint): `ardmk-init --cli` + * Create Arduino Uno Makefile (useful within a library example): `ardmk-init -b uno` * Create boilerplate Arduino Uno project in current working directory of same - name: `ardmk-init -b uno --quiet --project` + name: `ardmk-init -b uno --project` * Create Arduino-mk nano Makefile in current working directory with template .ino: - `ardmk-init -b nano -u atmega328 -qtn my-project` + `ardmk-init -b nano -u atmega328 -tn my-project` See `armk-init --help` for CLI arguments """ @@ -22,7 +22,7 @@ import os import argparse ## Global Vars -VERSION = "1.0" +VERSION = "1.1" ARD_TEMPLATE = "\n\ #include \n\ #include \n\ @@ -36,30 +36,32 @@ void loop() {\n\ " ## Command Parser -PARSER = argparse.ArgumentParser(description='Arduino Makefile and boilerplate project generator.\ +PARSER = argparse.ArgumentParser(prog='ardmk-init', + description='Arduino Makefile and boilerplate project generator.\ For use with Ard-Makefile: https://github.com/sudar/Arduino-Makefile.\ Script created by John Whittington https://github.com/tuna-f1sh 2017\ - \n\nVersion: ' + VERSION, usage='ardmk-init # prompted CLI, see --help for more.') + \n\nVersion: ' + VERSION) PARSER.add_argument('-v', '--verbose', action='store_true', help="print file contents during creation") -PARSER.add_argument('-d', '--directory', default=os.getcwd(), help='directory to run generator') +PARSER.add_argument('-d', '--directory', default=os.getcwd(), help='directory to run generator, default cwd') PARSER.add_argument('-b', '--board', default='uno', help='board tag') PARSER.add_argument('-u', '--micro', default='AUTO', help='microcontroller on board') PARSER.add_argument('-f', '--freq', default='AUTO', help='clock frequency') PARSER.add_argument('-p', '--port', default='AUTO', help='monitor port') PARSER.add_argument('-n', '--name', default=os.path.basename(os.getcwd()), help='project name') -PARSER.add_argument('-q', '--quiet', action='store_true', help='run quiet without user prompts') +PARSER.add_argument('--cli', action='store_true', help='run with user prompts (requires "Clint" module), rather than args') PARSER.add_argument('-P', '--project', action='store_true', help='create boilerplate project with src, lib and bin folder structure') PARSER.add_argument('-t', '--template', action='store_true', - help='create bare minimum Arduino source file') + help='create bare minimum Arduino source file') +PARSER.add_argument('-V', '--version', action='version', version='%(prog)s '+ VERSION) ARGS = PARSER.parse_args() try: from clint.textui import prompt, validators except ImportError: - if not ARGS.quiet: - print("Python module 'clint' is required for running prompted. Install the module or run with arguments only using --quiet") + if ARGS.cli: + print("Python module 'clint' is required for running prompted. Install the module or run with arguments only") quit() @@ -71,7 +73,7 @@ def generate_makefile(): file_content = "# Generated by ard-make version " + VERSION + "\n\n" # Basic - if not ARGS.quiet: + if ARGS.cli: print("Generating Arduino Ard-Makefile project in " + os.path.abspath(ARGS.directory)) btag = prompt.query('Board tag?', default='uno') @@ -94,13 +96,13 @@ def generate_makefile(): file_content += check_define('MONITOR_PORT', monitor_port) # Extended - if not ARGS.quiet: + if ARGS.cli: if not prompt.yn('Extended options?', default='n'): if not prompt.yn('Define local folders?', default='n'): - src_dir = prompt.query('Sources folder (Makefile will be created here)?',\ - default='', validators=[]) + src_dir = prompt.query('Sources folder (Makefile will be created here)?', + default='', validators=[]) userlibs = prompt.query('Library folder (will create if does not exist) - AUTO is Sketchbook directory?', - default='AUTO', validators=[]) + default='AUTO', validators=[]) obj_dir = prompt.query('Output directory?', default='AUTO', validators=[]) else: src_dir = '' @@ -171,9 +173,9 @@ def generate_makefile(): file_content += check_define('TARGET', ARGS.name) if not "ARDMK_DIR" in os.environ: - if ARGS.quiet: - puts(colored.magenta('Warning: ARDMK_DIR environment variable not defined. \ - Must be defined for Makefile to work')) + if not ARGS.cli: + print("Warning: ARDMK_DIR environment variable not defined. \ + Must be defined for Makefile to work") else: ardmk = prompt.query('Arduino Makefile path?', default='/usr/share/arduino', @@ -207,7 +209,7 @@ def write_template(filename): """ print("Writing " + os.path.abspath(filename) + ".ino...") if os.path.isfile(filename + '.ino'): - if ARGS.quiet: + if not ARGS.cli: print(filename + '.ino' + ' already exists! Stopping.') return print(filename + '.ino' + ' already exists! Overwrite?') @@ -241,15 +243,26 @@ def check_define(define, user): return string +def check_args(): + """ + Check input args will work with Makefile + """ + # Micro should be defined for non uno boards + if ARGS.board != 'uno' and ARGS.micro == 'AUTO': + print('\n!!! Warning: --micro should be defined and not left AUTO for non-Uno boards\n') + + if __name__ == '__main__': # Create directory if not exist check_create_folder(ARGS.directory) + # Check input args + check_args() # Change to dir so all commands are run relative os.chdir(ARGS.directory) if os.path.isfile('Makefile'): - if ARGS.quiet: + if not ARGS.cli: print('Makefile in ' + os.path.abspath(ARGS.directory) - + ' already exists! Stopping.') + + ' already exists! Please remove before generating. Stopping.') quit() # Confirm with user if not quiet mode