def clean_wcosa(path): """cleans the bin folder, deleting all the build files""" path = str(path) # confirm if bin folder/path exists if os.path.exists(helper.linux_path(path + '/wcosa/bin')): os.chdir(helper.linux_path(path + '/wcosa/bin')) else: output.writeln('\nNot a valid WCosa project', Fore.RED) quit(2) # check if the current build files are for the current board # clean and build if boards are different try: output.write('Cleaning build files - ', Fore.GREEN) for folder in helper.get_dirs(helper.get_working_directory()): shutil.rmtree(folder) for file in helper.get_files(helper.get_working_directory()): os.unlink(file) except IOError: output.writeln('Error while cleaning build files', Fore.RED) output.writeln('done')
def package_update_all(path): """Update all installed packages""" repo = package_repo_open(package_dir_path(path)) for sm in repo.submodules: write('Updating %s... ' % sm.name) remote = sm.module().remotes[0] remote.pull('-f') # sm.update is defective; use this instead. writeln('Done.') if repo.is_dirty(): # Something has changed repo.index.commit('Updated ' + sm.name)
def update_wcosa(path, board, ide): """Updates existing WCosa project""" path = str(path) write('Updating work environment - ', color=Fore.CYAN) verify_path(path) templates_path = helper.linux_path(helper.get_wcosa_path() + '/templates') user_config_path = path + '/config.json' internal_config_path = path + '/wcosa/internal-config.json' general_cmake_path = path + '/wcosa/CMakeLists.txt' # create src, lib, and wcosa folders create_folders(path) # copy all then CMakeLists templates and configuration templates copyfile(templates_path + '/cmake/CMakeLists.txt.tpl', general_cmake_path) copyfile(templates_path + '/config/internal-config.json.tpl', internal_config_path) # recopy any missing files if not os.path.exists(path + '/config.json'): copyfile(templates_path + '/config/config.json.tpl', user_config_path) writeln('done') write('Updating configurations with new changes - ', color=Fore.CYAN) user_data = config.fill_user_config(user_config_path, board, Port(None), ide) project_data = config.fill_internal_config(internal_config_path, path, user_data) cmake.parse_update(general_cmake_path, project_data) if user_data['ide'] == 'clion': copyfile(templates_path + '/ide/clion/CMakeListsPrivate.txt.tpl', path + '/CMakeListsPrivate.txt') # recopy any missing files if not os.path.exists(path + '/CMakeLists.txt'): copyfile(templates_path + '/ide/clion/CMakeLists.txt.tpl', path + '/CMakeLists.txt') if not os.path.exists(path + '/.gitignore-files'): copyfile(templates_path + '/gitignore-files/.gitignore-clion', path + '/.gitignore') cmake.parse_update(path + '/CMakeLists.txt', project_data) cmake.parse_update(path + '/CMakeListsPrivate.txt', project_data) elif not os.path.exists(path + '/.gitignore'): copyfile(templates_path + '/gitignore-files/.gitignore-general', path + '/.gitignore') writeln('done')
def package_repo_init(pkgpath): """Initialize package repo""" write('Initializing package repository... ') sys.stdout.flush() pkgrepo = git.Repo.init(pkgpath) pkglist_exists = os.path.exists(PACKAGE_LIST_FILE) if not pkglist_exists: with open(PACKAGE_LIST_FILE, 'w+') as pkglist: pkglist.write('[]') # Start with empty package list pkgrepo.index.commit('Initialized repository') writeln('Done') return pkgrepo
def package_uninstall(path, package, batch=False, pkgrepo=None, pkglist=None): """ Uninstall a package or unlink from given location if linked to multiple. If batch is True, do not update package list (caller will update). Returns True on success, else (on error) False. """ pkgpath = package_dir_path(path) if pkgrepo is None: pkgrepo = package_repo_open(pkgpath) if pkglist is None: pkglist = package_list_read(pkgpath) pkgnames = list(map(lambda x: x['name'], pkglist)) write('Uninstalling %s... ' % package.name) sys.stdout.flush() if package.name not in pkgnames: writeln('Not installed.') return False try: paths = pkglist[pkgnames.index(package.name)]['paths'] # Get paths try: os.unlink(path + '/' + package.path) except Exception: writeln('%s not linked at %s.' % (package.name, package.path)) return False if len(paths) > 1: # Installed in multiple locations writeln('Unlinked from %s.' % package.path) if not batch: package_list_remove_many(pkgpath, [package]) return True else: sm = pkgrepo.submodule(package.name) sm.remove(force=True) # Remove even if there are local changes pkgrepo.index.add(['.gitmodules']) pkgrepo.index.remove([package.name], r=True) # Remove recursively pkgrepo.index.commit('Uninstalled ' + package.name) if not batch: package_list_remove_many(pkgpath, [package]) except Exception as e: writeln('Failed to uninstall %s: %s' % (package.name, e)) return False else: writeln('Uninstalled.') return True
def _package_install_unsafe(path, package, pkgrepo, pkglist, pkgnames): """ NOT A PUBLIC INTERFACE: use package_install[_many] instead. Try to install a package and forward exceptions to the caller. Will leave package repository in dirty state. Returns """ write('Installing %s... ' % package.name) sys.stdout.flush() repo_path = package_repo_path(path, package) if package.name in pkgnames and os.path.exists(repo_path): index = pkgnames.index(package.name) link_path = package_link_path(path, package) if package.path in pkglist[index]['paths'] and os.path.lexists( link_path): writeln('Already installed.') raise AlreadyInstalledException(link_updated=False) else: write('Already installed, linking to %s... ' % package.path) sys.stdout.flush() package_link(path, package) writeln('Linked.') raise AlreadyInstalledException(link_updated=True) # If the above did not return, we need to actually install the package try: if package.branch: pkgrepo.create_submodule(package.name, package.name, url=package.url, branch=package.branch) else: pkgrepo.create_submodule(package.name, package.name, url=package.url) except Exception: # Default message is cryptic raise GitFetchException(package) package_link(path, package) writeln('Installed.')
def serial_monitor(port, baud): """ Open serial monitor to the specified port with the given baud rate. """ write('Serial Monitor ', Fore.CYAN) write(port, Fore.YELLOW) write(' @ ', Fore.CYAN) writeln(baud, Fore.YELLOW) sys.argv = ['monitor', '--exit-char', '3'] try: miniterm.main(default_port=port or serial_ports(), default_baudrate=baud or 9600) except KeyboardInterrupt: writeln('\nExiting serial monitor', Fore.CYAN)
def build_wcosa(path, generator=None, make=None, cmake=None, needs_cmake=True): """build wcosa project, cmake and make""" path = str(path) output.writeln('Wcosa project build started', Fore.GREEN) output.write('Verifying the project structure - ', Fore.GREEN) # check if path is valid if not os.path.exists(path): output.write('Project path is invalid: ' + path, Fore.RED) quit(2) # confirm if bin folder/path exists if os.path.exists(helper.linux_path(path + '/wcosa/bin')): os.chdir(helper.linux_path(path + '/wcosa/bin')) else: output.writeln('\nNot a valid WCosa project', Fore.RED) quit(2) output.writeln('done') cmake_program = cmake or get_cmake_program() make_program = make or get_make_program() output.write('Verifying cmake and make installs - ', Fore.GREEN) # check if cmake is in environment paths (unix/linux based systems) if not cmake_program: output.writeln( '\ncmake does not exist, please install it or make sure it is in your environment PATH', Fore.RED) quit(2) # check if make is in environment paths (unix/linux based systems) if not make_program: output.writeln( '\nmake does not exist, please install it or make sure it is in your environment PATH', Fore.RED) quit(2) output.writeln('done') if not generator or not str(generator): generator = Generator(get_generator_for(make_program)) # check if path is valid and get build information from the user config if not os.path.exists(path + '/config.json'): output.write( 'Project user configuration file does not exist, recreate or update the project', Fore.RED) quit(2) else: with open(path + '/config.json') as f: data = json.load(f, object_pairs_hook=OrderedDict) board = data['board'] # check if the current build files are for the current board # clean and build if boards are different if os.path.exists(helper.get_working_directory() + '/Makefile'): with open(helper.get_working_directory() + '/Makefile') as f: makefile_str = ''.join(f.readlines()) if '\n' + board not in makefile_str: output.writeln( 'Since a new board is detected, full build will be triggered', Fore.GREEN) clean_wcosa(path) if needs_cmake: output.writeln('Running the build using cmake and ' + str(generator), Fore.GREEN) cmake_code = subprocess.call(['cmake', '-G', str(generator), '..']) if cmake_code != 0: output.writeln( 'Project build unsuccessful, cmake exited with error code ' + str(cmake_code), Fore.RED) quit(2) make_code = subprocess.call([make_program]) # make returns 2 if the project has not been configured if make_code == 2 or make_code == '2': output.writeln('No Makefiles present, run wcosa build', Fore.RED) quit(2) if make_code != 0: output.writeln( 'Project build unsuccessful, make exited with error code ' + str(make_code), Fore.RED) quit(2) output.writeln('Project successfully built', Fore.GREEN)
def upload_wcosa(path, port): """upload wcosa project to the port specified or an automatically selected one""" path = str(path) output.writeln('Wcosa project upload started', Fore.GREEN) output.write('Verifying build files - ', Fore.GREEN) # confirm if bin folder/path exists if os.path.exists(helper.linux_path(path + '/wcosa/bin')): os.chdir(helper.linux_path(path + '/wcosa/bin')) else: output.writeln('\nNot a valid WCosa project', Fore.RED) # if project has not been built right if not os.path.exists(helper.get_working_directory() + '/Makefile'): output.writeln('\nNo Makefile, build the project first ', Fore.RED) quit(2) output.writeln('done') # check if path is valid and get the user config if not os.path.exists(path + '/config.json'): output.write( 'Project user configuration file does not exist, recreate or update the project', Fore.RED) quit(2) user_port = None data = None else: with open(path + '/config.json') as f: data = json.load(f, object_pairs_hook=OrderedDict) user_port = data['port'].strip(' ') if not port.use_same(): output.write('Using the port provided - ' + str(port), Fore.GREEN) else: # if port is defined in the config file, then use that port if user_port.lower() != 'None'.lower() and user_port != '': port = user_port output.writeln('Using the port from the config file: ' + user_port, Fore.GREEN) # check if the port is valid if port not in get_serial_devices(): output.writeln( '\nPort provided does not have a valid device connected to it', Fore.RED) quit(2) else: output.writeln('Automatically selecting a port', Fore.GREEN) port = serial_ports() output.writeln('Port chosen: ' + port, Fore.GREEN) # save the port in the config file so that update can update the project based on that temp_data = copy.copy(data) temp_data['port'] = str(port) with open(path + '/config.json', 'w') as f: json.dump(temp_data, f, indent=settings.get_settings_value('json-indent')) # do not print the updating logs output.output_status(False) # reset the port in the user config to the port that was there with open(path + '/config.json', 'w') as f: json.dump(data, f, indent=settings.get_settings_value('json-indent')) output.writeln('Upload triggered on ' + str(port), Fore.GREEN) upload_code = subprocess.call([get_make_program(), 'upload']) if upload_code != 0: output.writeln( 'Project upload unsuccessful, make exited with error code ' + str(upload_code), Fore.RED) quit(2) output.writeln('Project upload successful', Fore.GREEN)
def create_wcosa(path, board, ide): """Creates WCosa project from scratch""" path = str(path) write('Creating work environment - ', color=Fore.CYAN) verify_path(path) templates_path = helper.linux_path(helper.get_wcosa_path() + '/templates') user_config_path = helper.linux_path(path + '/config.json') internal_config_path = helper.linux_path(path + '/wcosa/internal-config.json') general_cmake_path = helper.linux_path(path + '/wcosa/CMakeLists.txt') src_path = helper.linux_path(path + '/src/main.cpp') # check if there are already src and lib folders. We do not want to delete those folders if len(helper.get_dirs(path)) > 0 and (os.path.exists(path + '/src') or os.path.exists(path + '/lib')): writeln( '\nThere is already a src and/or lib folder in this directory. Use wcosa update instead', color=Fore.RED) quit(2) # create src, lib, and wcosa folders create_folders(path, True) # copy all then CMakeLists templates and configuration templates copyfile(templates_path + '/cmake/CMakeLists.txt.tpl', general_cmake_path) copyfile(templates_path + '/config/internal-config.json.tpl', internal_config_path) copyfile(templates_path + '/config/config.json.tpl', user_config_path) copyfile(templates_path + '/examples/main.cpp', src_path) writeln('done') write('Updating configurations based on the system - ', color=Fore.CYAN) user_data = config.fill_user_config(user_config_path, board, Port(None), ide) project_data = config.fill_internal_config(internal_config_path, path, user_data) cmake.parse_update(general_cmake_path, project_data) if user_data['ide'] == 'clion': copyfile(templates_path + '/ide/clion/CMakeLists.txt.tpl', path + '/CMakeLists.txt') copyfile(templates_path + '/ide/clion/CMakeListsPrivate.txt.tpl', path + '/CMakeListsPrivate.txt') copyfile(templates_path + '/gitignore-files/.gitignore-clion', path + '/.gitignore') cmake.parse_update(path + '/CMakeLists.txt', project_data) cmake.parse_update(path + '/CMakeListsPrivate.txt', project_data) else: copyfile(templates_path + '/gitignore-files/.gitignore-general', path + '/.gitignore') writeln('done') writeln('Project Created and structure:', color=Fore.YELLOW) writeln('src -> All source files go here:', color=Fore.YELLOW) writeln('lib -> All custom libraries go here', color=Fore.YELLOW) writeln('wcosa -> All the build files are here (do no modify)', color=Fore.YELLOW)