#!/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 = "1.0" directory = os.getcwd() 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: 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(): # Header fileContents = "# 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))) 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: 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) # 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) # 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) 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 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: 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" # 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): 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) src.close() def checkCreateFolder(folder): 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): 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) 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()