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

Replace '-' with '_' in method names #373

Closed

Conversation

masayag
Copy link
Contributor

@masayag masayag commented Dec 8, 2018

When names of methods aren't conventional, a minor tweak can allow using
the auto-generated methods.

For instance, the CNI defines entity named NetworkAttachmentDefinition.
Its resource is network-attachment-definition, and to access the
resource a call should be made for:

/apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/ovs-foreman

However, with the current code, the generated methods for that resource
rely on the reported resource definition:

{
  "name"=>"network-attachment-definitions",
  "singularName"=>"network-attachment-definition",
  "namespaced"=>true,
  "kind"=>"NetworkAttachmentDefinition",
  "verbs"=>["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"],
  "shortNames"=>["net-attach-def"]
}

And by that, the stored information for the entity looks like:

 <OpenStruct entity_type="NetworkAttachmentDefinition",
             resource_name="network-attachment-definitions",
             method_names=["networkattachmentdefinition", "network-attachment-definitions"]>

This produces unsupported generated method names such as get_network-attachment-definitions
and watch_network-attachment-definitions which prevents client to access that resource.

The PR proposes to replace dashes with underscores to allow generation
of legal methods names, regardless of the weird naming.

@masayag masayag force-pushed the replace_dash_with_underscores branch from 93b8289 to 6b0ad50 Compare December 8, 2018 21:47
@cben
Copy link
Collaborator

cben commented Dec 8, 2018

Ooh, interesting find!
Can you add a test case? And a note in CANGELOG.
Also note rubocop complaint (bundle exec rake to run locally).

In this case, it's maybe better to rely on singularName which is more obviously symmetric with name, rather than hoping underscores inferred from capitalization of kind matches the dashes in name?
Though singularName is optional, so we'd also have to fallback onto kind, so maybe simpler as you wrote...
OK either way.

@masayag masayag force-pushed the replace_dash_with_underscores branch from 6b0ad50 to 50dfcc2 Compare December 8, 2018 22:43
@masayag
Copy link
Contributor Author

masayag commented Dec 8, 2018

@cben in terms of reducing any potential of regressions, I'd like to stay with my proposed PR, when the impacts are clear to me.

Fixed travis complains (use 'tr' instead of 'gsub' for performance).

  • added test for that special case

@masayag
Copy link
Contributor Author

masayag commented Dec 8, 2018

@cben when can we expect for a new release that will include this fix ?

@@ -156,7 +156,7 @@ def self.parse_definition(kind, name)
method_names = [singular_underscores, singular_underscores + plural_suffix]
else
# Something weird, can't infer underscores for plural so just give them up
Copy link
Member

Choose a reason for hiding this comment

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

is the comment still valid? it might be read as confusing along with code that actually adds underscores

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pls let me know if the updated comment makes more sense or requires any improvements / being removed entirely.

Copy link
Member

Choose a reason for hiding this comment

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

yes it does, thanks :)
I would say that "something weird" part is too generic and redundant, but it was here before, so I'm not insisting on taking it out.

@masayag masayag force-pushed the replace_dash_with_underscores branch from 50dfcc2 to 6df71c5 Compare December 9, 2018 15:09
@abonas
Copy link
Member

abonas commented Dec 10, 2018

@cben I'm leaving the merge to you, don't want to interfere with your release plans :)

@@ -74,4 +74,11 @@ def test_format_datetime_with_time
formatted = client.send(:format_datetime, value)
assert_equal(formatted, '2018-04-30T19:20:33.000000000+00:00')
end

def test_parse_definition_with_dashes_in_resource_name
method_names = Kubeclient::ClientMixin.parse_definition('TestNameWithDashes',\
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's use a singular kind here — 'TestNameWithDash'

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cben fixed.

@masayag masayag force-pushed the replace_dash_with_underscores branch from 6df71c5 to a7a0393 Compare December 10, 2018 09:33
method_names = Kubeclient::ClientMixin.parse_definition('TestNameWithDash',\
'test-name-with-dashes').method_names
assert_equal(method_names[0], 'testnamewithdash')
assert_equal(method_names[1], 'test_name_with_dashes')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wait, I missed this before, so we'll have get_testnamewithdash method for single entity but get_test_name_with_dashes for the collection?
I don't like this.

  • One direction is for this case to want consistent in get_test_name_with_dash, get_test_name_with_dashes.

    • one way we could obtain this is to use [singular_underscores, name.tr('-', '_')]. IFF kind's word boundaries match the plural dashes, a bit tricky to detect this...
    • another way is to use singularName! IFF it's specified, AND we're in "something weird" case so we give up relying on kind. [singular_name.tr('-', '_'), name.tr('-', '_')].
  • another direction is to drop the dashes, giving us get_testnamewithdash, get_testnamewithdashes.

The first direction is prettier — after all somebody went to non-standard trouble 😉 😇 to give us word boundaries in both singular and plural case — but I'm not sure how to detect this situation reliably.

PS. I think predictable method names are more important consideration than pretty. A dumber algorithm may be better if it's easier to explain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cben, have a look at the updated version and see if that's make sense to have.
Added few examples to test.
Please let me know if you'd like to include more cases or alter this PR.

@masayag masayag force-pushed the replace_dash_with_underscores branch from a7a0393 to 4ea2dde Compare December 10, 2018 12:30
# Something weird, can't infer underscores for plural so just give them up
method_names = [singular_name, name]
stripped_name = name.tr('-', '').tr('_', '') # clear separators
if stripped_name.start_with?(singular_name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

almost good, but maybe better check singular_underscores.start_with?(name.tr('-', '_')).
currently you can add this test: (wrong plurals intentional, correct "y" -> "ies" plural is broken #366 (comment))

      SameUptoWordboundary sameup-toword-boundarys same_upto_wordboundary sameup_toword_boundarys

where the resulting single vs plural boundaries differ! because stripped_name erased that info.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Did you mean the opposite ? Since singular_underscores is shorten than name and fails for all tests.

name.tr('-', '_').start_with?(singular_underscores)

However, with this change, your suggested test case
SameUptoWordboundary sameup-toword-boundarys same_upto_wordboundary sameup_toword_boundarys fails.

This test (and other) passes without changing the proposed code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, yes, opposite.

The test "case" was not really a suggested case to add as-is, just example of stripped_name.start_with?(singular_name) behavior, which I think is not good:

get_same_upto_wordboundary 
get_sameup_toword_boundarys

And I think desired behavior here is the last fallback of dropping the dashes:

get_sameuptowordboundary 
get_sameuptowordboundarys

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the PR to produce the desired naming. Add test with proper expectation for it.

@masayag masayag force-pushed the replace_dash_with_underscores branch from 4ea2dde to 59e1d72 Compare December 11, 2018 05:51
When names of methods aren't conventional, there will be an attempt to
produce method names based on the following logic:

1. If the plural name without separators starts with lower-cased 'kind',
   use underscores as separators (assuming plural has separators)
2. In case of a mismatch, remove any separators and plural name will be
   the lower-case of it.

For instance, the CNI defines entity named NetworkAttachmentDefinition.
Its resource is 'network-attachment-definition', so to access the
resource a call should be made for:

/apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions

However, with the current code, the generated methods for that resource
rely on the reported resource definition:

{
  "name"=>"network-attachment-definitions",
  "singularName"=>"network-attachment-definition",
  "namespaced"=>true,
  "kind"=>"NetworkAttachmentDefinition",
  "verbs"=>["delete", "deletecollection", "get", "list", "patch", "create", "update", "watch"],
  "shortNames"=>["net-attach-def"]
}

And by that, the stored information for the entity looks like:
 <OpenStruct entity_type="NetworkAttachmentDefinition",
             resource_name="network-attachment-definitions",
             method_names=["networkattachmentdefinition", "network-attachment-definitions"]>

This produces unsupported generated method names such as 'get_network-attachment-definitions'
and 'watch_network-attachment-definitions' which prevents client to access that resource.

Using the PR, the generated method names will be:
'get_network_attachment_definition' and 'get_network_definitions'.
@masayag
Copy link
Contributor Author

masayag commented Dec 19, 2018

@cben should this be merged to master first or should I create a PR for 4.1 branch ?

@masayag masayag closed this Dec 26, 2018
@masayag masayag deleted the replace_dash_with_underscores branch December 26, 2018 10:56
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.

3 participants