OyvindSabo / gremlint

Linter/Code formatter for Gremlin
https://gremlint.com
Apache License 2.0
11 stars 6 forks source link

TinkerPop's Style Guide #38

Open spmallette opened 4 years ago

spmallette commented 4 years ago

I came across this project after thinking (again) about an automated way to format Gremlin. It was nice to see that someone else was thinking of the same thing. I so often see a big one-liner of Gremlin posted on StackOverflow like:

g.V().as_("v").repeat(identity().as_("src").bothE().as_("e").bothV().as_("v").where(neq("src")).simplePath()).emit().filter(project("x","y","z").by(select(first, "v")).by(select(last, "v")).by(select("v").count(local)).as_("triple").coalesce(select("x","y").as_("a").select("triples").unfold().as_("t").select("x","y").where(eq("a")).select("t"),store("triples")).select("z").as_("length").select("triple").select("z").where(eq("length"))).select('e').unfold().groupCount().next()

and I know I can't possibly read that until I paste it into a notepad and add some indents:

g.V().as_("v").
  repeat(identity().as_("src").
         bothE().as_("e").
         bothV().as_("v").
         where(neq("src")).
         simplePath()).
    emit().
  filter(project("x","y","z").
           by(select(first, "v")).
           by(select(last, "v")).
           by(select("v").count(local)).as_("triple").
         coalesce(select("x","y").as_("a").
                  select("triples").unfold().as_("t").
                  select("x","y").
                  where(eq("a")).
                  select("t"),
                  store("triples")).
         select("z").as_("length").
         select("triple").
         select("z").
         where(eq("length"))).
   select('e').
   unfold().
   groupCount()

gremlint looks like a nice start to getting Gremlin looking pretty and the name (and art) is very cool. It appears as if you've been away from this project for a while but I do intend to promote it a bit to see if it might generate some interest in the TinkerPop community.

https://twitter.com/spmallette/status/1233386453234786305

All that said, I wanted to point out that TinkerPop does have a style guide for Gremlin which can be found in our Recipes. It would be really nice to see gremlint advance in that direction.

spmallette commented 4 years ago

@OyvindSabo I was just wondering if you still had interest in this project and what future plans you might have for it. Any thoughts?

OyvindSabo commented 4 years ago

Hey, @spmallette, I apologize for not getting back to you earlier. I do indeed have plans to continue working on it.

This has been at the back of my mind for the last months, and I've been working on gathering sample queries to write good test cases.

When I first wrote this, I had only been writing Gremlin every now and then for three or four months, doing really basic stuff, but since then Gremlin has become a natural part of my work life, and I use Gremlin for way more advanced stuff now, so I'm tempted to start over again with a blank sheet.

My opinion on what is good formatting has also changed considerably over the last year and a half (at the time of making this, I had not even read the style guide in Recipes).

For the next iteration I would like to make it more modular, making it easier to turn on and off individual rules, and perhaps even suggest what might cause the query to fail (e.g. using in instead of __.in and so on). The current implementation is just a huge behemoth of a function which does both formatting and color coding, and was largely written at an airport while waiting for my departure.

I would love for this to get more traction in the community, ideally getting the project to a state where we can have a continuous feedback loop with frequent improvements. Thanks for breathing new life to my inspiration:smiley:

spmallette commented 4 years ago

That is all very nice to hear. Glad to see that you intend to continue here and hopefully some folks in the TinkerPop community could help contribute.

For the next iteration I would like to make it more modular, making it easier to turn on and off individual rules, and perhaps even suggest what might cause the query to fail (e.g. using in instead of __.in and so on).

More modularity in the code would be good and help new contributors add things in a way that don't create more tangles. I like the idea of having rules that could be flipped on/off but also those that are configurable in some way. You may or may not want to get into suggesting fixes to errors which is more the job of the development environment/compiler imo but it's an interesting idea.

I do think that you should consider language specific formatting. Would be nice to get sane formatting for .NET that is different than Java for example.

Looking forward a bit, personally, I would like to see a tighter association between gremlint and our official Apache project. I see gremlint as providing a living style guide which enforces the rules we'd like to see in all Gremlin written. That's much better than the TinkerPop "style guide" written up in the bottom of our Recipes as documentation.

I'd like to continue our discussions on all this as time goes forward. Would you like to continue using this GitHub issue or is there a better way to get in touch with you? Are you on Twitter somewhere perhaps?

OyvindSabo commented 4 years ago

Yes, Gremlint mirroring the best practices from the Apache project would be the goal. I've never used Twitter, but maybe it's time I give it a try. For the time being I think this issue is a good place for further discussion.

OyvindSabo commented 3 years ago

@spmallette I released a new version of Gremlint yesterday. It's a complete rewrite which more properly parses queries to syntax trees, adds formatting information and then reprints them, taking into account a user-defined maximum line length, whether a step is a modulator, etc... Some work still remains, but I think it is already doing a better job reflecting the TinkerPop style guide. It also has a more modular architecture, which makes it easier to make iterative improvements. Lastly, I've also graduated from university now, which hopefully means I'll have more spare time to actively maintain the project.

spmallette commented 3 years ago

excellent! i will have to take a look at how you restructured the code later today. Nice to hear that you plan to keep maintaining the project.

https://twitter.com/spmallette/status/1287706967138590722

I'll re-iterate the notion that I think it would be great for the TinkerPop Community if gremlint could become the official living style guide for Gremlin. Would you be willing to consider contributing the work to live at the Apache Software Foundation within the TinkerPop project where you could continue to work on it there? If so, I would be happy to bring up the idea within the TinkerPop community to see what the reaction is. If you're not ready yet and like things the way they are, no worries - I just think that there is considerable benefit to both gremlint and TinkerPop if they are more tightly bound together. Looking forward to hearing what you think!

OyvindSabo commented 3 years ago

Thanks for another shoutout! If you haven't found it yet, the code of interest is probably here, as well as the surrounding files. The rest is just UI code. I'll give the subject of letting the project live within the TinkerPop project some thought and get back to you:)

spmallette commented 3 years ago

thanks for considering it. if there is anything you'd like to talk about privately or want to know more about why i think both projects would benefit, please feel free to email me directly:

my-github-username@gmail.com

spmallette commented 3 years ago

Another reason gremlint.com is so important is that groovysh, the basis for Gremlin Console, likes periods at ends of lines, but I tend to find that most Java developers prefer otherwise. If gremlint is able to convert easily between the two that saves a lot of time.

https://twitter.com/spmallette/status/1288074984817139713

OyvindSabo commented 3 years ago

When I first started using Gremlin, I also put the punctuation at the beginning of the lines, since that's what I was used to from Java and JavaScript, but switched after a while because it sometimes resulted in weirdly shaped queries which looked like they had these half-indentations, depending on how I let punctuation affect indentation.

Considering the following query (with a maximum line length of 40 characters):

g.V().
  hasLabel("person").
  group().
    by(values("name", "age").fold()).
  unfold().
  filter(
    select(values).
    count(local).
    is(gt(1)))

punctuation-at-end-of-line

Should the punctuation come after the indentation, like this:

g.V()
  .hasLabel("person")
  .group()
    .by(values("name", "age").fold())
  .unfold()
  .filter(
    select(values)
    .count(local)
    .is(gt(1)))

punctuation-after-indentation

or be part of the indentation, like this?:

g.V()
 .hasLabel("person")
 .group()
   .by(values("name", "age").fold())
 .unfold()
 .filter(
    select(values)
   .count(local)
   .is(gt(1)))

punctuation-as-part-of-indentation

I don't think it will be much work adding a toggle for switching punctuation position, as long as I know where to place it. I created a separate issue for it here

I might send you an email, in which case it's my-github-username-with-a-dot-in-the-middle@gmail.com