Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework particle.include and particle.ignore for CLI compile #646

Merged
merged 10 commits into from
Jun 13, 2023

Conversation

keeramis
Copy link
Contributor

@keeramis keeramis commented Jun 8, 2023

Description

The CLI cloud compile command has an undocumented pair of files particle.include and particle.ignore that modify which files are sent to the cloud compiler. The implementation is broken because adding files to particle.include strips the relative path.

This PR reworks the usage of particle.include and particle.include files such that the file pattern in those files are used to either include/remove those files from the list of files that is sent to the cloud compiler.

How to Test

  1. Setup particle-cli locally as per the instructions here
  2. Checkout this branch
  3. Run npm start -- compile <platform> </path/to/project>

Adding particle.include or particle.ignore files

The particle.include and particle.ignore files provide a way to include or exclude additional files from the cloud compiler. Please note that these files are only for special extras and the default files like the source and header files are handled separately and are not affected by the patterns specified in these two files. These files can be located either in the project's root directory or in any of its subdirectories.

When the particle.include file is placed in the root directory, files matching the specified patterns are searched recursively from the root directory. On the other hand, if the particle.include file is placed in a subdirectory, the search for matching files is performed recursively starting from that subdirectory as the base. The system automatically handles duplicates, so there is no need to worry about them.

Similarly, the particle.ignore file follows the same behavior, but instead of including files, it excludes files that match the specified patterns from being sent to the cloud compiler.

Related Issues / Discussions

https://app.shortcut.com/particle/story/119000/rework-particle-include-and-particle-ignore-functionality-in-cli-compile

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA
  • Problem and solution clearly stated
  • Tests have been provided
  • Docs have been updated
  • CI is passing

@keeramis keeramis changed the title Rework 'particle.include' and 'particle.ignore' functionality in CLI compile Rework 'particle.include'/'particle.ignore' functionality in CLI compile Jun 8, 2023
@keeramis keeramis changed the title Rework 'particle.include'/'particle.ignore' functionality in CLI compile Rework particle.include/particle.ignore functionality in CLI compile Jun 8, 2023
@keeramis keeramis changed the title Rework particle.include/particle.ignore functionality in CLI compile Rework particle.include and particle.ignore for CLI compile Jun 8, 2023
@keeramis keeramis force-pushed the bug/sc-119000/project-incl-files branch from 4f064eb to a095853 Compare June 8, 2023 19:54
@keeramis keeramis force-pushed the bug/sc-119000/project-incl-files branch from a317de1 to 9907954 Compare June 9, 2023 09:32
if (os.platform() === 'win32') {
// because glob pattern is always in posix format
found = found.map(file => path.win32.normalize(file));
}
Copy link
Contributor Author

@keeramis keeramis Jun 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently, glob.sync only works with POSIX formats, which caused it to return POSIX-formatted file paths even on Windows systems. There is a --posix: false that theoritically should help workaround this problem but that option is not working as expected. This has not been a problem in our codebase because the file paths were later processed by path.relative in cloud.js, which handled the necessary adjustments for the specific operating system but when I tried to write unit tests for that specific code, it started to make the tests fail on Windows.

I believe it's best to modify the behavior of glob.sync to generate Windows-formatted paths directly at the source. This way, we can eliminate the need for the caller to handle this issue.

@keeramis keeramis requested review from monkbroc and eberseth June 9, 2023 09:51
@keeramis
Copy link
Contributor Author

keeramis commented Jun 9, 2023

I verified Windows is OK as well! @monkbroc , and it adds the .def files even when the content is in unix format.

This was the particle.include file:

**/*.def

Here's the text from console.

windows-tracker-edge-and-include.txt

});
}

_getDefaultIncludes(files, dirname, { followSymlinks }) {
// Recursively find source files
Copy link

@eberseth eberseth Jun 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically speaking, the default list should probably only have the following specific patterns that are found in src/ and lib/src only:

  • project.properties
  • src/*.h,hpp,hxx,c,cpp,cxx
  • src/*.ino
  • src/build.mk
  • lib/src/*.h,hpp,hxx,c,cpp,cxx

We don't want to pick up anything in lib/usage/*.ino for example

Copy link
Contributor Author

@keeramis keeramis Jun 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eberseth Thanks for your feedback! I've made the suggested modifications. Just to confirm, are there any other significant patterns we should consider, given that we now focus on src/* and lib/src/* directories only, excluding other nested directories? With this, we will also no longer support the flat architecture like this - https://github.com/particle-iot/particle-cli/tree/master/test/__fixtures__/projects/legacy-flat

In summary:

  1. Flat architecture will not be suppoorted - https://github.com/particle-iot/particle-cli/tree/master/test/__fixtures__/projects/legacy-flat
  2. we have this structure of multiple header extensions in one of the tests - should we continue supporting it. https://github.com/particle-iot/particle-cli/tree/master/test/__fixtures__/projects/multiple-header-extensions
  3. another one we until-now support is this 'extended' structure where the helper is with in the /src https://github.com/particle-iot/particle-cli/tree/master/test/__fixtures__/projects/extended
  4. What about symlinks like this? I am changing their structure as well https://github.com/particle-iot/particle-cli/tree/master/test/__fixtures__/projects/symlink

A simple yes/no from you is sufficient for me to make the expected modifications.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • No flat format is fine.
  • We never documented all of the other header file extensions but changing the list will likely break libraries in the future; I suspect that list happened when porting Arduino libraries.
  • The helper in src structure seems weird at first, but I suspect that is common for anyone who has divided their project into subdirectories, which is probably not that uncommon.
  • I didn't realize we supported symlinks that way but it could be useful when dealing with shared codebases. But you can also fix this with a build.mk, which might be a better way to do this than symlinks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Thanks for the inputs. @rickkas7.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eberseth To continue supporting certain legacy project structures, I will keep the changes to the original ones I had. To make changes to remove support for legacy formats, I am leaning towards getting the requirements sorted more clearly and will create a separate PR with those changes. For now, let's keep this PR focused on the particle.include and ignore files.

Copy link
Member

@monkbroc monkbroc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I made a few suggestions. You can merge and release after addressing them.

src/cmd/cloud.js Outdated
Comment on lines 785 to 786
this._getCustomIncludes(files, dirname, { followSymlinks });
this._getDefaultIgnores(files, dirname, { followSymlinks });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put default ignores before custom includes so it's possible to re-include something that got ignored.

src/cmd/cloud.js Outdated
if (!globsToInclude || !globsToInclude.length) {
continue;
}
const globList = globsToInclude.map(g => g);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is thing line for?

src/cmd/cloud.js Outdated
}
const globList = globsToInclude.map(g => g);
const includePaths = utilities.globList(includeDir, globList, { followSymlinks });
result.push(...includePaths);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could just do includePaths.forEach((file) => files.add(file)); instead of putting them in another temporary array.

src/cmd/cloud.js Outdated
Comment on lines 790 to 791
Array.from(files.values()).sort();
files.forEach((file) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly this works but you're not getting the benefits of the sort

Suggested change
Array.from(files.values()).sort();
files.forEach((file) => {
const sortedFiles = Array.from(files.values()).sort();
sortedFiles.forEach((file) => {

const includesFile = path.join(dirname, settings.dirIncludeFilename);
const ignoreFile = path.join(dirname, settings.dirExcludeFilename);
let hasIncludeFile = false;
this._getDefaultIncludes(files, dirname, { followSymlinks });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention to stack the settings on top of each other? For example, the _getDefaultIncludes() will add a bunch of patterns then _getCustomIncludes() will add to the existing pattern list, and so on? Or if the custom list is present it will clear any of the default patterns?

Copy link
Contributor Author

@keeramis keeramis Jun 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom list will not clear the list of files added by the default list. The difference is in files added by the system (_getDefaultIncludes) vs. user (_getCustomIncludes)

Here's what you can expect from this functionality:

  1. _getDefaultIncludes will add the default files as provided in the list into a resultant array that will get sent to the cloud compiler. Default list doesn't look at user inputs. It checks the patterns from the system.
  2. _getCustomIncludes will include more files as per the patterns in the particle.include file as specified by the user. Files added in step1 are not cleared.
  3. _getDefaultIgnores will remove any files as specified by the system (currently only lib/helper/examples/)
  4. _getCustomIgnores will remove any files as specified by the user in the particle.ignore file.

@eberseth
Copy link

eberseth commented Jun 9, 2023

This repo and branch is what should be working for Monitor Edge. There are still files that are not picked up for some reason.
https://github.com/particle-iot-inc/morph-private/tree/feature/cloud-compile

I am using the following command to start the compile:

$ npm start -- compile tracker --target 4.1.0 ~/projects/morph/morph-cloudcomp

It errored out saying that it was missing lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/http_client.h

src/memfault_demo_http.c:9:10: fatal error: memfault-firmware-sdk/components/include/memfault/http/http_client.h: No such file or directory
    9 | #include "memfault-firmware-sdk/components/include/memfault/http/http_client.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

The other files I see missing for some reason are:

  • lib/memfault/examples/memfault_test/src/memfault_particle_user_config.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/debug_log.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/device_info.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/platform/overrides.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/platform/reboot_tracking.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/http_client.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/utils.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/panics/coredump.h

@eberseth
Copy link

eberseth commented Jun 9, 2023

This repo and branch is what should be working for Monitor Edge. There are still files that are not picked up for some reason. https://github.com/particle-iot-inc/morph-private/tree/feature/cloud-compile

I am using the following command to start the compile:

$ npm start -- compile tracker --target 4.1.0 ~/projects/morph/morph-cloudcomp

It errored out saying that it was missing lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/http_client.h

src/memfault_demo_http.c:9:10: fatal error: memfault-firmware-sdk/components/include/memfault/http/http_client.h: No such file or directory
    9 | #include "memfault-firmware-sdk/components/include/memfault/http/http_client.h"
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

The other files I see missing for some reason are:

  • lib/memfault/examples/memfault_test/src/memfault_particle_user_config.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/debug_log.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/device_info.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/platform/overrides.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/core/platform/reboot_tracking.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/http_client.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/http/utils.h
  • lib/memfault/src/memfault-firmware-sdk/components/include/memfault/panics/coredump.h

Nevermind

Copy link

@rickkas7 rickkas7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't go through the code or run it, but the concept looks good. When is this planned for release so I can update the docs?

@keeramis
Copy link
Contributor Author

@rickkas7 Currently my only ask for feedback is for this - #646 (comment)

Once I get clarification on the above, I will get this into the next CLI release.

@keeramis keeramis force-pushed the bug/sc-119000/project-incl-files branch from 29ace01 to ae25437 Compare June 12, 2023 16:07
@keeramis keeramis merged commit 27c20a3 into master Jun 13, 2023
@monkbroc monkbroc deleted the bug/sc-119000/project-incl-files branch January 19, 2024 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants