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

feat: suppport repo ls sub-namespace #768

Merged
merged 3 commits into from
Feb 3, 2023
Merged

feat: suppport repo ls sub-namespace #768

merged 3 commits into from
Feb 3, 2023

Conversation

wangxiaoxuan273
Copy link
Contributor

@wangxiaoxuan273 wangxiaoxuan273 commented Jan 28, 2023

Resolves #733

Test output on terminal:
image

Signed-off-by: wangxiaoxuan273 wangxiaoxuan119@gmail.com

@wangxiaoxuan273
Copy link
Contributor Author

wangxiaoxuan273 commented Jan 28, 2023

I have two design questions:

  • When engineering is a repository and a namespace, should example-registry/engineering return the engineering repository?

i.e. :

$ oras repo ls example-registry
employeehandbook
engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview

currently the engineering repository is not returned given example-registry/engineering.

$ oras repo ls example-registry/engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview
  • Which display is better?

currently:

$ oras repo ls example-registry/engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview

or

$ oras repo ls example-registry/engineering
bestpractices
newhires/onboarding
newhires/teamoverview

@qweeah
Copy link
Contributor

qweeah commented Jan 28, 2023

@qweeah Please take a look at the failed e2e CI test. It's likely that the failed test need to be changed for this feature.

Yes you are right. One assertion can be removed since oras repo ls $REG/$REPO_SUFFIX is now a valid input.

@qweeah
Copy link
Contributor

qweeah commented Jan 28, 2023

When engineering is a repository and a namespace, should example-registry/engineering return the engineering repository?

  • If a registry need to explicitly define a separate namespace concept from repository(e.g. ghcr, dockerhub), I don't think engineering can be a repository and a namespace at the same time.
  • If repository is only a slash separated path for a regsitry (e.g. ACR, MCR), engineering SHOULD be included in the result of oras repo ls example.registry/engineering. There is no need to hide the result of a full match.

@qweeah
Copy link
Contributor

qweeah commented Jan 28, 2023

Which display is better?

I think the latter is out-of-option. Consider the scenario: How can the result of oras repo ls some.registry/my/repo be displayed if my/repo is a repository?

Comment on lines 58 to 61
hostname, namespace, _ := strings.Cut(args[0], "/")
opts.hostname = hostname
opts.namespace = namespace
// namespace is invalid if a tag is provided
if strings.Contains(namespace, ":") {
return fmt.Errorf("invalid namespace")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we refactor this part into a function so that we can unit test it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Parsing can be simplified in an easier way.

If args[0] contains /, we can parse it using ParseReference(). Otherwise, it is a hostname.

Copy link
Contributor Author

@wangxiaoxuan273 wangxiaoxuan273 Jan 31, 2023

Choose a reason for hiding this comment

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

Used ParseReference and created the function parseRepoPath to use in RunE.

cmd/oras/repository/ls.go Show resolved Hide resolved
Comment on lines 94 to 98
before, after, found := strings.Cut(repopath, requestedNamespace)
if !found || after == "" || before != "" {
return false
}
return after[0] == '/'
Copy link
Contributor

Choose a reason for hiding this comment

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

It partially works and is not readable. Can we choose a simpler implementation?

The reason why it partially works is that the inNamespace("foo", "foo") returns false, which should be true. You need unit tests to ensure code quality.

Copy link
Contributor

Choose a reason for hiding this comment

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

It seems to be a UX issue other than a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used strings.HasPrefix(repopath, opts.namespace+"/") here after discussion.

@codecov-commenter
Copy link

codecov-commenter commented Jan 29, 2023

Codecov Report

Merging #768 (ff3849e) into main (9c91686) will decrease coverage by 1.15%.
The diff coverage is n/a.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@            Coverage Diff             @@
##             main     #768      +/-   ##
==========================================
- Coverage   63.86%   62.71%   -1.15%     
==========================================
  Files          19       20       +1     
  Lines         714      802      +88     
==========================================
+ Hits          456      503      +47     
- Misses        225      257      +32     
- Partials       33       42       +9     
Impacted Files Coverage Δ
internal/graph/graph.go 42.52% <0.00%> (ø)
cmd/oras/internal/option/remote.go 67.95% <0.00%> (+1.10%) ⬆️
cmd/oras/internal/option/target.go 21.68% <0.00%> (+1.68%) ⬆️
cmd/oras/internal/option/spec.go 17.24% <0.00%> (+17.24%) ⬆️

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

@shizhMSFT
Copy link
Contributor

I have two design questions:

  • When engineering is a repository and a namespace, should example-registry/engineering return the engineering repository?

i.e. :

$ oras repo ls example-registry
employeehandbook
engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview

currently the engineering repository is not returned given example-registry/engineering.

$ oras repo ls example-registry/engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview
  • Which display is better?

currently:

$ oras repo ls example-registry/engineering
engineering/bestpractices
engineering/newhires/onboarding
engineering/newhires/teamoverview

or

$ oras repo ls example-registry/engineering
bestpractices
newhires/onboarding
newhires/teamoverview

This is a good question. I would suggest the latter one:

$ oras repo ls example-registry/engineering
bestpractices
newhires/onboarding
newhires/teamoverview

In this way, it is more consistent with the UNIX ls command. In addition, it is more script-friendly that you can do

namespace=example-registry/engineering
oras repo ls $namespace | while read repo; do
    repo=$namespace/$repo
    echo Tags in $repo:
    oras repo tags $repo
    echo
done

@FeynmanZhou
Copy link
Member

@wangxiaoxuan273 I vote for the latter one and agree with @shizhMSFT 's suggestion.

@wangxiaoxuan273
Copy link
Contributor Author

Which display is better?

I think the latter is out-of-option. Consider the scenario: How can the result of oras repo ls some.registry/my/repo be displayed if my/repo is a repository?

Then oras repo ls some.registry/my/repo does not return 'my/repo', if we choose the latter one.
Update: we've decided to use the latter display.

@wangxiaoxuan273 wangxiaoxuan273 requested review from shizhMSFT and removed request for FeynmanZhou February 3, 2023 06:41
@@ -60,15 +68,34 @@ Example - List the repositories under the registry that include values lexically
return cmd
}

func parseRepoPath(opts *repositoryOptions, arg string) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add unit tests for this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added unit tests.

return err
}
opts.hostname = reference.Registry
opts.namespace = reference.Repository
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
opts.namespace = reference.Repository
opts.namespace = reference.Repository + "/"

so that we don't need to calculate it multiple time in a loop at line 96.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed accordingly.

Signed-off-by: wangxiaoxuan273 <wangxiaoxuan119@gmail.com>
Signed-off-by: wangxiaoxuan273 <wangxiaoxuan119@gmail.com>
Signed-off-by: wangxiaoxuan273 <wangxiaoxuan119@gmail.com>
Copy link
Contributor

@shizhMSFT shizhMSFT left a comment

Choose a reason for hiding this comment

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

LGTM

@shizhMSFT shizhMSFT merged commit 076d859 into oras-project:main Feb 3, 2023
@wangxiaoxuan273 wangxiaoxuan273 deleted the sub-namespaces branch February 3, 2023 11:19
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.

oras repo ls to support sub namespaces
5 participants