* Snapshot Testing Proof of Concept (#5754)
### The problem
We currently do not have UI tests on a component level. Integrating snapshot tests would allow us to have peace of mind with each PR that it isn't going to introduce any changes to the UI unless its intended to.
### The solution
* Integrate `ios-snapshot-test-case` pod to handle generating and diffing images of components.
* Integrate `git-lfs` to handle storage of the goldens.
This PR creates one test to showcase the ability to do snapshot tests. Upon merging this PR, you must install git-lfs in order to properly have the images pulled down. The 3 steps to do this:
1. `brew install git-lfs`
2. `git lfs install`
3. `git lfs pull`
Additionally, the golden is generated using an iOS 11 simulator at 2x scale so that the kokoro jobs are happy.
### Related bugs
Closes#5740
### Difference from #5754
**Note:** This is a re-revert of #5754 that aims to fix issues with Travis CI by ensuring the snapshot test only runs on a single iOS version. I've opened #5888 to expand on this in the future. A few things changed in the approach in this PR:
* We only run the snapshot test for iOS 11.2.0 until we can have an elegant solution for supporting multiple OS''s (see #5888)
* The snapshot tests now live in their own test target to avoid issues with having to require an App host for all tests.
* Additionally, a dummy swift file was required for compilation of this new test target (see https://forums.developer.apple.com/thread/88451 for context)
### The problem
We currently do not have UI tests on a component level. Integrating snapshot tests would allow us to have peace of mind with each PR that it isn't going to introduce any changes to the UI unless its intended to.
### The solution
* Integrate `ios-snapshot-test-case` pod to handle generating and diffing images of components.
* Integrate `git-lfs` to handle storage of the goldens.
This PR creates one test to showcase the ability to do snapshot tests. Upon merging this PR, you must install git-lfs in order to properly have the images pulled down. The 3 steps to do this:
1. `brew install git-lfs`
2. `git lfs install`
3. `git lfs pull`
Additionally, the golden is generated using an iOS 11 simulator at 2x scale so that the kokoro jobs are happy.
### Related bugs
Closes#5740
### Context
When determining whether a change affects multiple components we want to ignore changes to CocoaPods files that live outside of the components directories.
### The problem + fix
Prior to this change, if a commit modified MaterialComponentsAlpha.podspec or catalog/Podfile it was being picked up as a multi-component change in the release notes.
After this change, commits affecting those files will not be treated as multi-component changes unless they also touch other files in the repo.
### Opportunities for further improvement
It's likely fair to say that any modification to files outside of the `components/` directory can be ignored. I'm not sure what the best way to filter these types of changes is, but that would be a welcome follow-up simplification of this change that would require less on-going maintenance.
The script now outputs four groups of changelogs:
1. Breaking changes for specific components.
2. Breaking changes across multiple components.
3. Changes for specific components.
4. Changes acrosss multiple components.
This will make it easier for us to keep all google-owned repositories running the same clang-format version in tandem.
Also moved from a submodule to a clone + version checkout so that our CI gracefully upgrades as we release new non-breaking release to clang-format-ci.
Relies on upstream changes in https://github.com/material-foundation/clang-format-ci/pull/4
{MDC iOS} No longer using `-init` for Color Scheme.
Based on the discussions in go/mdc-ios-theming, we should not use the `-init` default initializer. Instead, we should use an explicit set of defaults.
Search regex: '\[\[MDCSemanticColorScheme alloc\] init\]'
## Context
Two libraries have graduated from the material-components-ios repo so that they can be used more generally across other open source projects: [clang-format-ci](https://github.com/material-foundation/clang-format-ci) and [github-comment](https://github.com/material-foundation/github-comment).
## What's going on here
Both of these libraries have been added as external submodule dependencies and the scripts have been updated to refer to the new external dependency paths.
## Prior to this change
Our test_all script was using an Xcode schemes search and filter to identify any test schemes that exist in the repository and test them. Unfortunately, the script was not also testing to confirm that it found at least *some* tests, meaning if it did not find any tests it would silently succeed.
The script was essentially optimized for us adding multiple test schemes in the future. In practice, the frequency with which we add new test schemes is low (we've added only one in the past year via MaterialComponentsAlpha).
## The root cause
With d238c86d47eb072617d285106147ace613321aee, our Xcode test scheme names changed and our scheme search was no longer returning our unit test schemes, resulting in test_all succeeding even though it hadn't run any tests.
## After this change
The test_all script will explicitly test specific schemes. If these schemes change or move in the future, this script will fail until we also update the script's schemes.
This script now also pipes the test output through xcpretty if it is available.
Closes https://github.com/material-components/material-components-ios/issues/5539
This add the shape theming doc generation for our components. Same as we did for color, we are adding the shape theming template so then it can be easily generated for our docs. I will generate the shape theming docs for our components in a follow up PR.
Prior to this change, `Component+Extension` additions would be incorrectly listed as a "New component" in the API diff.
After this change, `Componet+Extension` additions will be listed as "New extension" in the API diff.
This ensures that if a piece of feedback moves around within a given file (e.g. because lines were added or removed above this feedback) that we won't erroneously post the same comment again.
This job is our first official linter.
<img width="830" alt="screen shot 2018-08-30 at 5 12 35 pm" src="https://user-images.githubusercontent.com/45670/44880230-d8049780-ac79-11e8-926b-836b16c86f9f.png">
See https://github.com/material-components/material-components-ios/pull/4954 for an example thread in which I purposefully made some style regressions and let the tool post back to the PR until I resolved them.
This new job will apply clang-format *only* to the lines that have been changed by a given pull request. If any changes are suggested, the diff will be shown in the job's build logs and individual changes will be posted back to the PR at each suggested line.
The provided feedback can be addressed in multiple ways:
1. Manually, by copying the suggested changes into your code.
2. By running git-clang-format on your local branch. The tool will suggest this, including an ideal command line invocation to do so.
This job can be run locally, though it requires a fair amount of configuration to do so. See the job's documentation for more details on which environment variables are required.
---
This change also required modifications to the github-comment command line tool. Notably:
1. A very light-weight diff parser was added. This API takes a git diff [unified diff](https://www.gnu.org/software/diffutils/manual/html_node/Example-Unified.html#Example-Unified) file and parses it into individual [hunks](https://www.gnu.org/software/diffutils/manual/html_node/Hunks.html).
2. A hunk-correlator was added. This is the magic that translates clang-format's suggested diff into individual positions on a GitHub pull request.
3. A new GitHub API method for fetching a single file was added. We require this in order to fetch the pull request diff.
4. A new set of command line parameters was added to the github-comment tool. Use of these new parameters turn a suggested diff into a series of GitHub pull request line comments.
Before posting any new comments to the PR, the command enumerates all of the existing comments into a Set. If desired comment already exists in the set of comments then it will not be posted again. This is the mechanism by which we minimize noise generated from the job on subsequent updates to the PR.
---
The essential workflow for this tool is (on kokoro):
1. Install the clang-format version we're using internally by fetching it from our pre-built binary repository: https://github.com/material-foundation/clang-format
2. Install the git-clang-format tool.
3. Verify the checksums of both tools.
4. Run git-clang-format on the pull request.
5. If there have been no changes, exit with status 0 and post success back to the PR. Deletes any comment that had been made previously about style (this matches the apidiff behavior).
6. Otherwise, output the diff results and feed the diff to github-comment.
7. github-comment parses the pull request diff and the suggested diff, correlates the suggested hunks with the pull request hunks, and then posts individual line comments with the suggested changes.
8. If a summary comment hasn't already been posted to the PR, a summary comment is posted. Otherwise, we update the existing comment.
9. Post a failure status to the PR.
This resolves a warning that was appearing when building/running the github-comment project:
```
warning: Ignoring duplicate product 'github-comment'
```
Tested by running:
```
cd scripts/github-comment/
swift run github-comment
```
And verifying that the above warning did not appear and that the command successfully built and executed.
The umbrellas command is fed in to the apidiff tool as a filter for which components to look at.
Prior to this change, the umbrellas command was ignoring the apidiff base sha and always generating results from origin/stable.
After this change, the umbrellas and files commands will both accept an optional base sha from which to generate results.
Tested by running:
```bash
./scripts/release umbrellas HEAD
# Should output nothing
```
The release engineer is expected to fill these sections in by gathering the information from the commits. If information is not available in a given commit, then the release engineer is expected to reach out to the commit author and ask them to provide the additional information (and encouraging them to do so in their commits in the future).
Once installed, clang-format can be run on only the lines that have been changed by a given range of commits like so:
# Format changes from develop to HEAD
git clang-format develop
Running this command will change files locally. You must then commit the changes and push them to your PR.
This change ensures that our release notes include API diffs for sub-components such as our themers.
Closes https://github.com/material-components/material-components-ios/issues/3983
Example output:
### AppBar+ColorThemer
#### MDCAppBarColorThemer
*new* class method: `+applySurfaceVariantWithColorScheme:toAppBarViewController:` in `MDCAppBarColorThemer`
*new* class method: `+applyColorScheme:toAppBarViewController:` in `MDCAppBarColorThemer`
### AppBar
#### MDCAppBarContainerViewController
*new* property: `appBarViewController` in `MDCAppBarContainerViewController`
#### MDCAppBarNavigationControllerDelegate
*new* method: `-appBarNavigationController:willAddAppBarViewController:asChildOfViewController:` in `MDCAppBarNavigationControllerDelegate`
#### MDCAppBarViewController
*new* property: `navigationBar` in `MDCAppBarViewController`
*new* property: `headerStackView` in `MDCAppBarViewController`
*new* class: `MDCAppBarViewController`
As part of our readme generator, components can now opt in to displaying badges in their readme.
The badges are generated from https://shields.io/ and are focused on an individual component. We're currently generating the following badges:
- Open bug count.
This command will generate an API diff for the current pull request. In a follow-up PR it will also post the results of the API diff to the PR as a comment.
This is the first of two changes to the `apidiff` branch that will add support for API diff reporting to our PRs. The second PR will add the github comment reporting tool.
This was previously reviewed in https://github.com/material-components/material-components-ios/pull/4181.
This PR adds a new script, `scripts/generate_readme`, which will generate a root README.md file for a component from the component's docs/ content.
The advantages of this script over our current process of writing readmes:
- Documentation articles can be broken out into separate files, making it easier to generate and apply templates.
- Our component readmes now have auto-generated table of contents.
- Our documentation can be written in plain markdown with minimal material.io html magic.
- Having docs in separate files doesn't result in multiple "component pages" on material.io - everything ends up in a single component document on the site. E.g. the "Color Theming" article no longer shows up as its own link on material.io.
Example usage:
```bash
./scripts/generate_readme ActivityIndicator
```
---
The script makes the following assumptions:
A component has the following directory structure:
```
components/
Component/
README.md <- The component's main readme.
This is the readme that will show up on material.io.
docs/
README.md <- A skeletal readme with links to other docs files.
some-article.md <- An article that may be linked to.
```
`components/Component/docs/README.md` is treated as a standard markdown file, with the additional interpretations:
```
* [Text](url)
Treated as an icon list for the material.io website.
If the url links to any go/design- url, the link will use the spec icon
- [Text](some-article.md)
Indicates that the linked article should be added verbatim to the main README.md
<!-- toc -->
A table of contents should be generated here.
```
The script then does the following:
1. Generates a template README from the component's .vars file.
2. Appends the component's docs/README.md to the readme.
3. Rewrites any asset and relative url paths.
4. Transforms all `* [text](link)`-formatted link lists into icon-list lists.
4b. If an icon list url points to a design site, the spec icon will be used for the list item.
5. Replaces every `- [text](link)`-formatted link list item with the contents of the file.
6. Generates a table of contents if `<!-- toc -->` is found. The table of contents will include all level 2 and 3 headers found after the toc tag.
7. Copies the output to the component's root README.md.
The implication of this script is that we can now write documentation as small files which are easier to templatize. These smaller files can be aggregated together into a single larger README.md that is consumable by the material.io website.
Example of table of contents on material.io:
<img width="460" alt="screen shot 2018-05-01 at 9 07 31 am" src="https://user-images.githubusercontent.com/45670/39473887-1fa6c85c-4d1f-11e8-8620-d6b151a315c6.png">