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

Path pattern builder #809

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open

Path pattern builder #809

wants to merge 39 commits into from

Conversation

noodlze
Copy link

@noodlze noodlze commented Feb 22, 2023

Motivation:
Addresses #659.

  • Add PathPattern#of accepting PathPattern... pathPatterns
PathPattern.of(PatternPattern.of("json"), PathPattern.startsWith("/foo/bar"));
  • Add PathPatternBuilder to provide a way to combination many patterns into one.
    The following initial options have been added:
startsWith(String dirPath)

contains(String dirPath)

endsWith(String filename) 
//or
extension(String extension)

Modifications:

  • PathPatternOption, PathPathOptions -> define and manage the options available.
  • PathPatternBuilder -> responsible for composing one pathPattern from the added options.
    • Can only use one of the options endsWith or extension ; currently, option added after will override previous

Result:

PathPattern.of(PatternPattern.of("json"), PathPattern.startsWith("/foo/bar"));

PathPattern.builder().startsWith("/foo/bar").build(); // "/foo/bar/**"

PathPattern.builder()
                    .startsWith("/foo/bar")
                    .endsWith("foo.txt")
                     .build(); // "/foo/bar/**/foo.txt"
                           
 PathPattern.builder()
                      .startsWith("/foo")
                      .contains("/bar/")
                      .extension("json")
                      .build() // "/foo/**/bar/**/*.json"

 PathPattern.builder()
                     .startsWith("/foo")
                     .endsWith("qux.json")
                     .extension("json")
                     .build() // "/foo/**/*.json"

@CLAassistant
Copy link

CLAassistant commented Feb 22, 2023

CLA assistant check
All committers have signed the CLA.

@codecov
Copy link

codecov bot commented Feb 22, 2023

Codecov Report

Patch coverage: 85.93% and project coverage change: -0.05 ⚠️

Comparison is base (bda3bec) 65.71% compared to head (53ebe9f) 65.67%.

Additional details and impacted files
@@             Coverage Diff              @@
##             master     #809      +/-   ##
============================================
- Coverage     65.71%   65.67%   -0.05%     
- Complexity     3289     3337      +48     
============================================
  Files           350      356       +6     
  Lines         13731    13911     +180     
  Branches       1488     1510      +22     
============================================
+ Hits           9024     9136     +112     
- Misses         3863     3921      +58     
- Partials        844      854      +10     
Impacted Files Coverage Δ
.../com/linecorp/centraldogma/common/PathPattern.java 62.50% <40.00%> (-37.50%) ⬇️
...necorp/centraldogma/common/PathPatternBuilder.java 92.30% <92.30%> (ø)
...necorp/centraldogma/common/DefaultPathPattern.java 97.95% <100.00%> (+0.52%) ⬆️

... and 17 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@noodlze
Copy link
Author

noodlze commented Feb 27, 2023

We may allow multiple contains unlike other methods such as startWith() and enddWith().

  • startsWith() supports only one path. We can simply set the value as a string field.
    endsWith() and extension() are mutually exclusive. We can make the methods override the same field.
public final class PathPatternBulider {

    @Nullable
    private String startPattern;
    @Nullable
    private String endPattern;
    @Nullable
    private List<String> innerPatterns;

    public PathPatternBuilder startsWith(String dirPath) {
        // validation and normalize ...
        this.startPattern = dirPath;
    }


    public PathPatternBuilder extension(String extension) {
        // validation and normalize ...
        this.endPattern = normalize(extension);
    }
}

As a result of moving the pattern build order logic from PathPatternOption to PathPatternBuilder , precedence info stored in PathPatternOption is no longer needed.
Also, it's harder to determine whether endsWith/extension option has been added more than once with this new structure as adding either will simply override any existing value stored in endPattern. It's easy to do so for startPattern since there is only one option (startsWith). So in the end, for consistency, I found it simpler to just allow adding same option twice to the builder; when we add the same option, it will just override existing.

@noodlze noodlze requested review from ikhoon and removed request for trustin, jrhee17 and minwoox February 27, 2023 00:13
Copy link
Contributor

@ikhoon ikhoon left a comment

Choose a reason for hiding this comment

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

Overall looks good. Left minor comments.

@noodlze noodlze requested a review from ikhoon March 3, 2023 00:40
Copy link
Contributor

@ikhoon ikhoon 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! 🚀:tada:

@noodlze noodlze requested review from trustin and removed request for jrhee17 and minwoox March 6, 2023 23:25
if (pathPatterns.length == 1) {
return pathPatterns[0];
}
return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return new DefaultPathPattern(ImmutableList.copyOf(pathPatterns));
return new DefaultPathPattern(ImmutableSet.copyOf(pathPatterns));

Copy link
Author

@noodlze noodlze Mar 20, 2023

Choose a reason for hiding this comment

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

Previously, a new constructor for DefaultPathPattern(List<PathPattern> verifiedPatterns) was introduced that would skip the validatePathPattern step.
I changed the argument type from List<PathPattern> -> varargs PathPattern... in commit 0d85d78.

Comment on lines 44 to 48
@Nullable
private PathPatternOption startPattern;
private final List<PathPatternOption> innerPatterns = new ArrayList<>();
@Nullable
private PathPatternOption endPattern;
Copy link
Member

Choose a reason for hiding this comment

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

Can't we just use PathPattern here?

/**
* A {@link PathPatternBuilder} option.
*/
final class PathPatternOption {
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if this class is needed at all. Why do we need to create a PathPattern lazily? Can't we just create it as early as possible?

Copy link
Author

Choose a reason for hiding this comment

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

I have merged PathPatternOptions and PathPatternOption with PathPatternBuilder

Comment on lines +75 to +85
assertThat(PathPattern.builder()
.contains("/foo")
.contains("/bar")
.build()
.patternString()).isEqualTo("/**/foo/**/bar/**");
assertThat(PathPattern.builder()
.startsWith("/foo/bar")
.startsWith("/override")
.hasExtension("json")
.build()
.patternString()).isEqualTo("/override/**/*.json");
Copy link
Member

Choose a reason for hiding this comment

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

I think this can be quite confusing to users. Should we always override, even for contains()?

Copy link
Author

@noodlze noodlze Mar 22, 2023

Choose a reason for hiding this comment

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

Hi @trustin ,
Your point about differing behavior for contains(combining allowed) vs other options (combining not allowed , will override) being confusing is valid.
I also understand @ikhoon point's that, when considered in isolation, contains can be combined (ref #809 (comment) ).
Personally, I am on the fence, with no strong opinion.
Perhaps @minwoox , and @jrhee17 could share their opinion :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants