Beispiel #1
0
def create_boards_tree(board_file_path, new_board_path):
    """Create a json version of boards file from cosa"""

    with open(helper.linux_path(board_file_path)) as f:
        board_str = f.readlines()

    tree = {}
    curr_board = ''

    for line in board_str:
        if 'name=' in line:
            curr_board = line[:line.find('.')]
            tree[curr_board] = {}
            tree[curr_board]['name'] = line[line.find('='):].strip('=').strip(
                '\n').strip(' ')
        elif 'mcu=' in line:
            tree[curr_board]['mcu'] = line[line.find('='):].strip('=').strip(
                '\n').strip(' ')
        elif 'f_cpu=' in line:
            tree[curr_board]['f_cpu'] = line[line.find('='):].strip('=').strip(
                '\n').strip(' ')
        elif 'board=' in line:
            tree[curr_board]['id'] = line[line.find('='):].strip('=').strip(
                '\n').strip(' ')

    with open(helper.linux_path(new_board_path), 'w') as f:
        json.dump(tree, f, indent=4)
Beispiel #2
0
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')
Beispiel #3
0
def get_board_properties(board, board_path):
    """parses the board file returns the properties of the board specified"""

    with open(helper.linux_path(board_path)) as f:
        board_data = json.load(f, object_pairs_hook=OrderedDict)

    return board_data[board]
Beispiel #4
0
def fill_internal_config(path, curr_path, user_config_data):
    """fills the internal config file that will be used for internal build"""

    with open(helper.linux_path(path)) as f:
        internal_config_data = json.load(f, object_pairs_hook=OrderedDict)

    internal_config_data['project-name'] = os.path.basename(curr_path)
    internal_config_data['ide'] = user_config_data['ide']
    internal_config_data['board'] = user_config_data['board']
    internal_config_data['port'] = user_config_data['port']
    internal_config_data['wcosa-path'] = helper.get_wcosa_path()
    internal_config_data['current-path'] = helper.linux_path(curr_path)
    internal_config_data['cmake-version'] = settings.get_settings_value(
        'cmake-version')

    # get c and cxx flags
    board_properties = board_parser.get_board_properties(
        user_config_data['board'],
        internal_config_data['wcosa-path'] + '/wcosa/boards.json')
    internal_config_data[
        'cmake-c-flags'] = platform_parser.get_c_compiler_flags(
            board_properties, internal_config_data['wcosa-path'] +
            '/toolchain/cosa/platform.txt',
            settings.get_settings_value('include-extra-flags'))
    internal_config_data[
        'cmake-cxx-flags'] = platform_parser.get_cxx_compiler_flags(
            board_properties, internal_config_data['wcosa-path'] +
            '/toolchain/cosa/platform.txt',
            settings.get_settings_value('include-extra-flags'))
    internal_config_data['cmake-cxx-standard'] = settings.get_settings_value(
        'cmake-cxx-standard')
    internal_config_data['custom-definitions'] = user_config_data[
        'build-flags']
    internal_config_data['module-definitions'] = user_config_data[
        'module-flags']
    internal_config_data['cosa-libraries'] = user_config_data['cosa-libraries']

    with open(helper.linux_path(path), 'w') as f:
        json.dump(internal_config_data,
                  f,
                  indent=settings.get_settings_value('json-indent'))

    return internal_config_data
Beispiel #5
0
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')
Beispiel #6
0
def get_all_board(board_path):
    """parses the board file returns the properties of the board specified"""

    with open(helper.linux_path(board_path)) as f:
        board_data = json.load(f, object_pairs_hook=OrderedDict)

    keys = []

    for key in board_data:
        keys.append(key)

    return keys
Beispiel #7
0
def fill_user_config(path, board, port, ide):
    """fills the user config file that will be used for internal build"""

    with open(helper.linux_path(path)) as f:
        user_config_data = json.load(f, object_pairs_hook=OrderedDict)

    if not board.use_same():
        user_config_data['board'] = str(board)

    if not ide.use_same():
        user_config_data['ide'] = str(ide)

    if not port.use_same():
        user_config_data['port'] = str(port)

    user_config_data['framework'] = settings.get_settings_value('framework')

    with open(helper.linux_path(path), 'w') as f:
        json.dump(user_config_data,
                  f,
                  indent=settings.get_settings_value('json-indent'))

    return user_config_data
Beispiel #8
0
def get_c_compiler_flags(board_properties, platform_path, include_extra=True):
    """Get template filled c compiler flags"""

    with open(helper.linux_path(platform_path)) as f:
        raw_flags = get_raw_flags(f.readlines(), 'c', include_extra)

    processed_flags = ''

    for flag in raw_flags.split(' '):
        data = {
            'build.mcu': board_properties['mcu'],
            'build.f_cpu': board_properties['f_cpu'],
            'runtime.ide.version':
            settings.get_settings_value('arduino-version')
        }
        processed_flags += helper.fill_template(flag, data) + ' '

    return processed_flags.strip(' ')
Beispiel #9
0
def parse_update(tpl_path, project_data):
    """reads the cmake template file and completes it using project data"""

    tpl_path = helper.linux_path(tpl_path)
    tpl_file = open(tpl_path)
    tpl_str = tpl_file.readlines()
    tpl_file.close()

    new_str = ''
    index = 0
    while index < len(tpl_str):
        curr_line = tpl_str[index]
        compare_tag = curr_line.strip('\n').strip(' ')

        # handle loop statements
        if compare_tag == LIB_SEARCH_TAG:
            result = get_elements(tpl_str, index)

            new_str += lib_search(result[0], project_data)
            index = result[1]
        elif compare_tag == COSA_SEARCH_TAG:
            result = get_elements(tpl_str, index)

            new_str += cosa_search(result[0], project_data)
            index = result[1]
        elif compare_tag == FIRMWARE_GEN_TAG:
            result = get_elements(tpl_str, index)

            new_str += firmware_gen(result[0], project_data)
            index = result[1]
        elif compare_tag == DEF_SEARCH_TAG:
            result = get_elements(tpl_str, index)

            new_str += def_search(result[0], project_data)
            index = result[1]
        else:
            new_str += helper.fill_template(curr_line, project_data)
        index += 1

    tpl_file = open(tpl_path, 'w')
    tpl_file.write(new_str)
    tpl_file.close()
Beispiel #10
0
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)
Beispiel #11
0
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)
Beispiel #12
0
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)