diff --git a/.github/workflows/test-python-poetry-task.yml b/.github/workflows/test-python-poetry-task.yml index c52a3799..76f9b39d 100644 --- a/.github/workflows/test-python-poetry-task.yml +++ b/.github/workflows/test-python-poetry-task.yml @@ -98,14 +98,14 @@ jobs: # codecov/codecov-action only makes the conversion if the `coverage` package is installed in the global runner # environment - - name: Convert code coverage report to format required by Codecov - run: | - poetry run \ - coverage xml \ - -o "${{ github.workspace }}/${{ env.COVERAGE_DATA_FILENAME }}" + #- name: Convert code coverage report to format required by Codecov + # run: | + # poetry run \ + # coverage xml \ + # -o "${{ github.workspace }}/${{ env.COVERAGE_DATA_FILENAME }}" - - name: Upload coverage report to Codecov - uses: codecov/codecov-action@v3 - with: - fail_ci_if_error: true - file: ${{ env.COVERAGE_DATA_FILENAME }} + #- name: Upload coverage report to Codecov + # uses: codecov/codecov-action@v3 + # with: + # fail_ci_if_error: true + # file: ${{ env.COVERAGE_DATA_FILENAME }} diff --git a/README.md b/README.md index f9d2c5c0..fd526d6d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +## This is my fork of Arduino's compile sketches action. + +I mostly just wanted to experiment with GitHub actions, but also I wanted to make some customizations to this one. The main thing I changed was making it compatible with Teensy's memory usage report. It also makes the .hex file that results from compilation available to download in an artifact file. + +Below this point, this is just a copy of the original ReadMe. + # `arduino/compile-sketches` action [![Check Action Metadata status](https://github.com/arduino/compile-sketches/actions/workflows/check-action-metadata-task.yml/badge.svg)](https://github.com/arduino/compile-sketches/actions/workflows/check-action-metadata-task.yml) diff --git a/compilesketches/compilesketches.py b/compilesketches/compilesketches.py index 23467799..9af0a92f 100644 --- a/compilesketches/compilesketches.py +++ b/compilesketches/compilesketches.py @@ -1,3 +1,10 @@ +''' +To push commits to the V1.1 tag: +commit changes to main +git tag -f v1.1 +git push origin HEAD +git push origin -f v1.1 +''' import atexit import time import contextlib @@ -14,6 +21,8 @@ import urllib import urllib.request +import inspect + import git import gitdb.exc import github @@ -101,6 +110,7 @@ class RunCommandOutput(enum.Enum): board_manager_platforms_path = arduino_cli_data_directory_path.joinpath("packages") class ReportKeys: + ############## Rewritten to support Teensy Compiler output ############## boards = "boards" board = "board" commit_hash = "commit_hash" @@ -117,6 +127,14 @@ class ReportKeys: minimum = "minimum" maximum = "maximum" sketches = "sketches" + code = "code" + data = "data" + headers = "headers" + free_for_files = "free_for_files" + variables = "variables" + padding = "padding" + free_for_local_variables = "free_for_local_variables" + free_for_malloc_new = "free_for_malloc_new" dependency_name_key = "name" dependency_version_key = "version" @@ -240,10 +258,35 @@ def compile_sketches(self): self.create_sketches_report_file(sketches_report=sketches_report) + self.copy_hex_files_to_artifacts_folder(sketch_report_list=sketch_report_list) + if not all_compilations_successful: print("::error::One or more compilations failed") sys.exit(1) + def copy_hex_files_to_artifacts_folder(self, sketch_report_list): + """Copy the hex files to the artifacts folder. + + Keyword arguments: + sketch_report_list -- list of dictionaries containing the sketch reports + """ + self.verbose_print("Copying hex files to artifacts folder") + self.verbose_print("Artifacts folder:", os.environ["GITHUB_WORKSPACE"]) + self.verbose_print(sketch_report_list) + + arduino_temp_folder_location = "/tmp/arduino/sketches/" + for sketch_report in sketch_report_list: + # get a list of directories in the temp folder + temp_folder_contents = os.listdir(arduino_temp_folder_location) + for folder in temp_folder_contents: + # self.verbose_print("::warning::Folder:", folder) + # self.verbose_print("::warning::hex file: " + arduino_temp_folder_location + folder + "/" + sketch_report["name"] + ".ino.hex") + hex_file_name = arduino_temp_folder_location + folder + "/" + sketch_report["name"] + ".ino.hex" + # copy the hex file to the sketches report path + sketches_report_path = absolute_path(path=self.sketches_report_path) + shutil.copy(hex_file_name, sketches_report_path) + + def install_arduino_cli(self): """Install Arduino CLI.""" self.verbose_print("Installing Arduino CLI version", self.cli_version) @@ -1012,68 +1055,164 @@ def get_sketch_report(self, compilation_result): def get_sizes_from_output(self, compilation_result): """Parse the stdout from the compilation process and return a list containing memory usage data. + ############## Rewritten to support Teensy Compiler output ############## + Keyword arguments: compilation_result -- object returned by compile_sketch() + + Memory Usage on Teensy 4.0: + FLASH: code:66336, data:12724, headers:9000 free for files:1943556 + RAM1: variables:19712, code:64184, padding:1352 free for local variables:439040 + RAM2: variables:12416 free for malloc/new:511872 + + self.ReportKeys.code + self.ReportKeys.data + self.ReportKeys.headers + self.ReportKeys.free_for_files + self.ReportKeys.variables + self.ReportKeys.padding + self.ReportKeys.free_for_local_variables + self.ReportKeys.free_for_malloc_new """ memory_types = [ { "name": "flash", - # Use capturing parentheses to identify the location of the data in the regular expression "regex": { - # The regular expression for the absolute memory usage - self.ReportKeys.absolute: r"Sketch uses ([0-9]+) bytes .*of program storage space\.", - # The regular expression for the total memory - self.ReportKeys.maximum: ( - r"Sketch uses [0-9]+ bytes .*of program storage space\. Maximum is ([0-9]+) bytes." - ), + self.ReportKeys.code: r"FLASH: code:([0-9]+), data:[0-9]+, headers:[0-9]+ free for files:[0-9]+", + self.ReportKeys.data: r"FLASH: code:[0-9]+, data:([0-9]+), headers:[0-9]+ free for files:[0-9]+", + self.ReportKeys.headers: r"FLASH: code:[0-9]+, data:[0-9]+, headers:([0-9]+) free for files:[0-9]+", + self.ReportKeys.free_for_files: r"FLASH: code:[0-9]+, data:[0-9]+, headers:[0-9]+ free for files:([0-9]+)" }, }, { - "name": "RAM for global variables", + "name": "RAM1", "regex": { - self.ReportKeys.absolute: r"Global variables use ([0-9]+) bytes .*of dynamic memory", - self.ReportKeys.maximum: ( - r"Global variables use [0-9]+ bytes .*of dynamic memory.*\. Maximum is ([0-9]+) bytes." - ), + self.ReportKeys.variables: r"RAM1: variables:([0-9]+), code:[0-9]+, padding:[0-9]+ free for local variables:[0-9]+", + self.ReportKeys.code: r"RAM1: variables:[0-9]+, code:([0-9]+), padding:[0-9]+ free for local variables:[0-9]+", + self.ReportKeys.padding: r"RAM1: variables:[0-9]+, code:[0-9]+, padding:([0-9]+) free for local variables:[0-9]+", + self.ReportKeys.free_for_local_variables: r"RAM1: variables:[0-9]+, code:[0-9]+, padding:[0-9]+ free for local variables:([0-9]+)" + }, + }, + { + "name": "RAM2", + "regex": { + self.ReportKeys.variables: r"RAM2: variables:([0-9]+) free for malloc/new:[0-9]+", + self.ReportKeys.free_for_malloc_new: r"RAM2: variables:[0-9]+ free for malloc/new:([0-9]+)" }, }, ] sizes = [] for memory_type in memory_types: - size = { - self.ReportKeys.name: memory_type["name"], - # Set default memory usage value, to be used if memory usage can't be determined - self.ReportKeys.absolute: self.not_applicable_indicator, - self.ReportKeys.maximum: self.not_applicable_indicator, - self.ReportKeys.relative: self.not_applicable_indicator, - } + if memory_type["name"] == "flash": + # Flash memory usage is reported in the stdout of the compilation process + size = { + self.ReportKeys.name: memory_type["name"], + # Set default memory usage value, to be used if memory usage can't be determined + self.ReportKeys.code: self.not_applicable_indicator, + self.ReportKeys.data: self.not_applicable_indicator, + self.ReportKeys.headers: self.not_applicable_indicator, + self.ReportKeys.free_for_files: self.not_applicable_indicator, + } + if compilation_result.success is True: + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.code, + ) + #self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(size_data)) + if size_data: + size[self.ReportKeys.code] = size_data - if compilation_result.success is True: - # Determine memory usage of the sketch by parsing Arduino CLI's output - size_data = self.get_size_data_from_output( - compilation_output=compilation_result.output, - memory_type=memory_type, - size_data_type=self.ReportKeys.absolute, - ) - if size_data: - size[self.ReportKeys.absolute] = size_data + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.data, + ) + + size[self.ReportKeys.data] = size_data + + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.headers, + ) + + size[self.ReportKeys.headers] = size_data + + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.free_for_files, + ) + size[self.ReportKeys.free_for_files] = size_data + elif memory_type["name"] == "RAM1": + size = { + self.ReportKeys.name: memory_type["name"], + # Set default memory usage value, to be used if memory usage can't be determined + self.ReportKeys.variables: self.not_applicable_indicator, + self.ReportKeys.code: self.not_applicable_indicator, + self.ReportKeys.padding: self.not_applicable_indicator, + self.ReportKeys.free_for_local_variables: self.not_applicable_indicator, + } + if compilation_result.success is True: size_data = self.get_size_data_from_output( compilation_output=compilation_result.output, memory_type=memory_type, - size_data_type=self.ReportKeys.maximum, + size_data_type=self.ReportKeys.variables, ) if size_data: - size[self.ReportKeys.maximum] = size_data + size[self.ReportKeys.variables] = size_data - size[self.ReportKeys.relative] = round( - (100 * size[self.ReportKeys.absolute] / size[self.ReportKeys.maximum]), - self.relative_size_report_decimal_places, + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.code, ) - sizes.append(size) + size[self.ReportKeys.code] = size_data + + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.padding, + ) + + size[self.ReportKeys.padding] = size_data + + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.free_for_local_variables, + ) + + size[self.ReportKeys.free_for_local_variables] = size_data + elif memory_type["name"] == "RAM2": + size = { + self.ReportKeys.name: memory_type["name"], + # Set default memory usage value, to be used if memory usage can't be determined + self.ReportKeys.variables: self.not_applicable_indicator, + self.ReportKeys.free_for_malloc_new: self.not_applicable_indicator, + } + if compilation_result.success is True: + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.variables, + ) + if size_data: + size[self.ReportKeys.variables] = size_data + size_data = self.get_size_data_from_output( + compilation_output=compilation_result.output, + memory_type=memory_type, + size_data_type=self.ReportKeys.free_for_malloc_new, + ) + + size[self.ReportKeys.free_for_malloc_new] = size_data + sizes.append(size) + #self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(sizes)) return sizes def get_size_data_from_output(self, compilation_output, memory_type, size_data_type): @@ -1086,6 +1225,8 @@ def get_size_data_from_output(self, compilation_output, memory_type, size_data_t """ size_data = None regex_match = re.search(pattern=memory_type["regex"][size_data_type], string=compilation_output) + #self.verbose_print('::warning::Test warning 3') + #self.verbose_print('::warning::Compilation output - ' + compilation_output) if regex_match: size_data = int(regex_match.group(1)) else: @@ -1105,7 +1246,6 @@ def get_size_data_from_output(self, compilation_output, memory_type, size_data_t + memory_type["name"] + "\". The board's platform may not have been configured to provide this information." ) - return size_data def get_warning_count_from_output(self, compilation_result): @@ -1179,58 +1319,182 @@ def get_sizes_report(self, current_sizes, previous_sizes): def get_size_report(self, current_size, previous_size): """Return a list of the combined current and previous size data, with deltas. + ############## Rewritten to support Teensy Compiler output ############## + Keyword arguments: current_size -- data from the compilation of the sketch at the pull request's head ref previous_size -- data from the compilation of the sketch at the pull request's base ref, or None if the size deltas feature is not enabled - """ - size_report = { - self.ReportKeys.name: current_size[self.ReportKeys.name], - self.ReportKeys.maximum: current_size[self.ReportKeys.maximum], - self.ReportKeys.current: { - self.ReportKeys.absolute: current_size[self.ReportKeys.absolute], - self.ReportKeys.relative: current_size[self.ReportKeys.relative], - }, - } + """ + #self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + "current_size: " + str(current_size)) + #self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + "previous_size: " + str(previous_size)) + if current_size[self.ReportKeys.name] == "flash": + size_report = { + self.ReportKeys.name: current_size[self.ReportKeys.name], + self.ReportKeys.current: { + self.ReportKeys.code: current_size[self.ReportKeys.code], + self.ReportKeys.data: current_size[self.ReportKeys.data], + self.ReportKeys.headers: current_size[self.ReportKeys.headers], + self.ReportKeys.free_for_files: current_size[self.ReportKeys.free_for_files], + }, + } + elif current_size[self.ReportKeys.name] == "RAM1": + size_report = { + self.ReportKeys.name: current_size[self.ReportKeys.name], + self.ReportKeys.current: { + self.ReportKeys.variables: current_size[self.ReportKeys.variables], + self.ReportKeys.code: current_size[self.ReportKeys.code], + self.ReportKeys.padding: current_size[self.ReportKeys.padding], + self.ReportKeys.free_for_local_variables: current_size[self.ReportKeys.free_for_local_variables], + }, + } + elif current_size[self.ReportKeys.name] == "RAM2": + size_report = { + self.ReportKeys.name: current_size[self.ReportKeys.name], + self.ReportKeys.current: { + self.ReportKeys.variables: current_size[self.ReportKeys.variables], + self.ReportKeys.free_for_malloc_new: current_size[self.ReportKeys.free_for_malloc_new], + }, + } + if previous_size is not None and current_size[self.ReportKeys.name] == "flash": + # Calculate the memory usage change + if ( + current_size[self.ReportKeys.code] == self.not_applicable_indicator + or previous_size[self.ReportKeys.code] == self.not_applicable_indicator + ): + code_delta = self.not_applicable_indicator + else: + code_delta = current_size[self.ReportKeys.code] - previous_size[self.ReportKeys.code] - if previous_size is not None: + if ( + current_size[self.ReportKeys.data] == self.not_applicable_indicator + or previous_size[self.ReportKeys.data] == self.not_applicable_indicator + ): + data_delta = self.not_applicable_indicator + else: + data_delta = current_size[self.ReportKeys.data] - previous_size[self.ReportKeys.data] + + if ( + current_size[self.ReportKeys.headers] == self.not_applicable_indicator + or previous_size[self.ReportKeys.headers] == self.not_applicable_indicator + ): + headers_delta = self.not_applicable_indicator + else: + headers_delta = current_size[self.ReportKeys.headers] - previous_size[self.ReportKeys.headers] + + if ( + current_size[self.ReportKeys.free_for_files] == self.not_applicable_indicator + or previous_size[self.ReportKeys.free_for_files] == self.not_applicable_indicator + ): + free_for_files_delta = self.not_applicable_indicator + else: + free_for_files_delta = current_size[self.ReportKeys.free_for_files] - previous_size[self.ReportKeys.free_for_files] + + + # Size deltas reports are enabled + # Print the memory usage change data to the log + delta_message = "Change in " + str(current_size[self.ReportKeys.name]) + ": " + self.ReportKeys.code + ": " + str(code_delta) + ", " + self.ReportKeys.data + ": " + str(data_delta) + ", " + self.ReportKeys.headers + ": " + str(headers_delta) + ", " + self.ReportKeys.free_for_files + ": " + str(free_for_files_delta) + + print(delta_message) + + size_report[self.ReportKeys.previous] = { + self.ReportKeys.code: previous_size[self.ReportKeys.code], + self.ReportKeys.data: previous_size[self.ReportKeys.data], + self.ReportKeys.headers: previous_size[self.ReportKeys.headers], + self.ReportKeys.free_for_files: previous_size[self.ReportKeys.free_for_files], + } + size_report[self.ReportKeys.delta] = { + self.ReportKeys.code: code_delta, + self.ReportKeys.data: data_delta, + self.ReportKeys.headers: headers_delta, + self.ReportKeys.free_for_files: free_for_files_delta, + } + elif previous_size is not None and current_size[self.ReportKeys.name] == "RAM1": # Calculate the memory usage change if ( - current_size[self.ReportKeys.absolute] == self.not_applicable_indicator - or previous_size[self.ReportKeys.absolute] == self.not_applicable_indicator + current_size[self.ReportKeys.variables] == self.not_applicable_indicator + or previous_size[self.ReportKeys.variables] == self.not_applicable_indicator ): - absolute_delta = self.not_applicable_indicator + variables_delta = self.not_applicable_indicator else: - absolute_delta = current_size[self.ReportKeys.absolute] - previous_size[self.ReportKeys.absolute] + variables_delta = current_size[self.ReportKeys.variables] - previous_size[self.ReportKeys.variables] if ( - absolute_delta == self.not_applicable_indicator - or size_report[self.ReportKeys.maximum] == self.not_applicable_indicator + current_size[self.ReportKeys.code] == self.not_applicable_indicator + or previous_size[self.ReportKeys.code] == self.not_applicable_indicator ): - relative_delta = self.not_applicable_indicator + code_delta = self.not_applicable_indicator else: - # Calculate from absolute values to avoid rounding errors - relative_delta = round( - (100 * absolute_delta / size_report[self.ReportKeys.maximum]), - self.relative_size_report_decimal_places, - ) + code_delta = current_size[self.ReportKeys.code] - previous_size[self.ReportKeys.code] + + if ( + current_size[self.ReportKeys.padding] == self.not_applicable_indicator + or previous_size[self.ReportKeys.padding] == self.not_applicable_indicator + ): + padding_delta = self.not_applicable_indicator + else: + padding_delta = current_size[self.ReportKeys.padding] - previous_size[self.ReportKeys.padding] + + if ( + current_size[self.ReportKeys.free_for_local_variables] == self.not_applicable_indicator + or previous_size[self.ReportKeys.free_for_local_variables] == self.not_applicable_indicator + ): + free_for_local_variables_delta = self.not_applicable_indicator + else: + free_for_local_variables_delta = current_size[self.ReportKeys.free_for_local_variables] - previous_size[self.ReportKeys.free_for_local_variables] + # Size deltas reports are enabled # Print the memory usage change data to the log - delta_message = "Change in " + str(current_size[self.ReportKeys.name]) + ": " + str(absolute_delta) - if relative_delta != self.not_applicable_indicator: - delta_message += " (" + str(relative_delta) + "%)" + delta_message = "Change in " + str(current_size[self.ReportKeys.name]) + ": " + self.ReportKeys.variables + ": " + str(variables_delta) + ", " + self.ReportKeys.code + ": " + str(code_delta) + ", " + self.ReportKeys.padding + ": " + str(padding_delta) + ", " + self.ReportKeys.free_for_local_variables + ": " + str(free_for_local_variables_delta) + print(delta_message) size_report[self.ReportKeys.previous] = { - self.ReportKeys.absolute: previous_size[self.ReportKeys.absolute], - self.ReportKeys.relative: previous_size[self.ReportKeys.relative], + self.ReportKeys.variables: previous_size[self.ReportKeys.variables], + self.ReportKeys.code: previous_size[self.ReportKeys.code], + self.ReportKeys.padding: previous_size[self.ReportKeys.padding], + self.ReportKeys.free_for_local_variables: previous_size[self.ReportKeys.free_for_local_variables], } size_report[self.ReportKeys.delta] = { - self.ReportKeys.absolute: absolute_delta, - self.ReportKeys.relative: relative_delta, + self.ReportKeys.variables: variables_delta, + self.ReportKeys.code: code_delta, + self.ReportKeys.padding: padding_delta, + self.ReportKeys.free_for_local_variables: free_for_local_variables_delta, } + elif previous_size is not None and current_size[self.ReportKeys.name] == "RAM2": + # Calculate the memory usage change + if ( + current_size[self.ReportKeys.variables] == self.not_applicable_indicator + or previous_size[self.ReportKeys.variables] == self.not_applicable_indicator + ): + variables_delta = self.not_applicable_indicator + else: + variables_delta = current_size[self.ReportKeys.variables] - previous_size[self.ReportKeys.variables] + + if ( + current_size[self.ReportKeys.free_for_malloc_new] == self.not_applicable_indicator + or previous_size[self.ReportKeys.free_for_malloc_new] == self.not_applicable_indicator + ): + free_for_malloc_new_delta = self.not_applicable_indicator + else: + free_for_malloc_new_delta = current_size[self.ReportKeys.free_for_malloc_new] - previous_size[self.ReportKeys.free_for_malloc_new] + # Size deltas reports are enabled + # Print the memory usage change data to the log + delta_message = "Change in " + str(current_size[self.ReportKeys.name]) + ": " + self.ReportKeys.variables + ": " + str(variables_delta) + ", " + self.ReportKeys.free_for_malloc_new + ": " + str(free_for_malloc_new_delta) + + print(delta_message) + + size_report[self.ReportKeys.previous] = { + self.ReportKeys.variables: previous_size[self.ReportKeys.variables], + self.ReportKeys.free_for_malloc_new: previous_size[self.ReportKeys.free_for_malloc_new], + } + size_report[self.ReportKeys.delta] = { + self.ReportKeys.variables: variables_delta, + self.ReportKeys.free_for_malloc_new: free_for_malloc_new_delta, + } + #self.verbose_print("size_report: " + str(size_report)) return size_report def get_warnings_report(self, current_warnings, previous_warnings): @@ -1294,6 +1558,9 @@ def get_sketches_report(self, sketch_report_list): def get_sizes_summary_report(self, sketch_report_list): """Return the list containing a summary of size data for all sketch compilations for each memory type. + ############## Rewritten to support Teensy Compiler output ############## + ############## NOT DONE YET ############## + Keyword arguments: sketch_report_list -- list of reports from each sketch compilation """ @@ -1301,28 +1568,35 @@ def get_sizes_summary_report(self, sketch_report_list): for sketch_report in sketch_report_list: for size_report in sketch_report[self.ReportKeys.sizes]: # Determine the sizes_summary_report index for this memory type + #self.verbose_print("::warning::size_report: " + str(size_report)) size_summary_report_index_list = [ index for index, size_summary in enumerate(sizes_summary_report) if size_summary.get(self.ReportKeys.name) == size_report[self.ReportKeys.name] ] + if not size_summary_report_index_list: # There is no existing entry in the summary list for this memory type, so create one sizes_summary_report.append({self.ReportKeys.name: size_report[self.ReportKeys.name]}) size_summary_report_index = len(sizes_summary_report) - 1 else: size_summary_report_index = size_summary_report_index_list[0] - - if ( - self.ReportKeys.maximum not in sizes_summary_report[size_summary_report_index] - or sizes_summary_report[size_summary_report_index][self.ReportKeys.maximum] - == self.not_applicable_indicator - ): - sizes_summary_report[size_summary_report_index][self.ReportKeys.maximum] = size_report[ - self.ReportKeys.maximum - ] - - if self.ReportKeys.delta in size_report: + + #self.verbose_print("::warning::size_report @" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(size_report)) + #self.verbose_print("::warning::sizes_summary_report @" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(sizes_summary_report)) + #self.verbose_print("::warning::size_summary_report_index_list @" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(size_summary_report_index_list)) + + if self.ReportKeys.current not in sizes_summary_report[size_summary_report_index]: + sizes_summary_report[size_summary_report_index][self.ReportKeys.current] = size_report[self.ReportKeys.current] + if self.ReportKeys.previous not in sizes_summary_report[size_summary_report_index]: + sizes_summary_report[size_summary_report_index][self.ReportKeys.previous] = size_report[self.ReportKeys.previous] + if self.ReportKeys.delta not in sizes_summary_report[size_summary_report_index]: + sizes_summary_report[size_summary_report_index][self.ReportKeys.delta] = size_report[self.ReportKeys.delta] + + #self.verbose_print("::warning::sizes_summary_report @" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + ": " + str(sizes_summary_report)) + + ### this section is not needed for Teensy Compiler output since deltas are embedded in each section anyways ### + '''if self.ReportKeys.delta in size_report: if ( self.ReportKeys.delta not in sizes_summary_report[size_summary_report_index] or sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ @@ -1367,8 +1641,37 @@ def get_sizes_summary_report(self, sketch_report_list): sizes_summary_report[size_summary_report_index][self.ReportKeys.delta][ self.ReportKeys.relative - ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][self.ReportKeys.relative] - + ][self.ReportKeys.maximum] = size_report[self.ReportKeys.delta][self.ReportKeys.relative]''' + + + ''' + The following "warnings" generate build annotations in the GitHub UI. + They output the memory usage data to the log as warnings which in turn generate build annotation in the GitHub UI. + ''' + memoryUsageReport = " Flash: code - " + memoryUsageReport += str(sizes_summary_report[0][self.ReportKeys.current][self.ReportKeys.code]) + memoryUsageReport += ", data - " + memoryUsageReport += str(sizes_summary_report[0][self.ReportKeys.current][self.ReportKeys.data]) + memoryUsageReport += ", headers - " + memoryUsageReport += str(sizes_summary_report[0][self.ReportKeys.current][self.ReportKeys.headers]) + memoryUsageReport += ", free for files - " + memoryUsageReport += str(sizes_summary_report[0][self.ReportKeys.current][self.ReportKeys.free_for_files]) + self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + memoryUsageReport) + memoryUsageReport = " RAM1: variables - " + memoryUsageReport += str(sizes_summary_report[1][self.ReportKeys.current][self.ReportKeys.variables]) + memoryUsageReport += ", code - " + memoryUsageReport += str(sizes_summary_report[1][self.ReportKeys.current][self.ReportKeys.code]) + memoryUsageReport += ", padding - " + memoryUsageReport += str(sizes_summary_report[1][self.ReportKeys.current][self.ReportKeys.padding]) + memoryUsageReport += ", free for local variables - " + memoryUsageReport += str(sizes_summary_report[1][self.ReportKeys.current][self.ReportKeys.free_for_local_variables]) + self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + memoryUsageReport) + memoryUsageReport = " RAM2: variables - " + memoryUsageReport += str(sizes_summary_report[2][self.ReportKeys.current][self.ReportKeys.variables]) + memoryUsageReport += ", free for malloc/new - " + memoryUsageReport += str(sizes_summary_report[2][self.ReportKeys.current][self.ReportKeys.free_for_malloc_new]) + self.verbose_print("::warning::@" + str(inspect.getframeinfo(inspect.currentframe()).lineno) + memoryUsageReport) + return sizes_summary_report def get_warnings_summary_report(self, sketch_report_list):