Closed noniq closed 7 years ago
I’m not sure what to do about the overhead, though … any ideas?
No, not really. Provide an API that will run the command in the background and recommend using that in the documentation?
You could use TextMate.detach
with a block to then run the executable found by Executable.find
in the background. But it still means that we go through the overhead twice – once when finding the executable, and (at least) once more when it is actually invoked. Not sure we can do anything about that 😞
I have an idea regarding the overhead when detecting a RVM executable:
We could introduce some kind of power user setting like TM_ALWAYS_ASSUME_RVM
, and if this is set we’d just skip the check in line 69 and simply return rvm . do <executable>
.
This would save the overhead of invoking rvm . do
just to check if the executable is installed, for the cost of harder to debug errors if an executable is indeed not installed. But users using this setting this would be expected to be able to deal with that.
I'm not sure. @sorbits @infininight any ideas about what to do with the overhead of rvm . do
?
Any news on this? Shall we proceed and get this merged?
@noniq what do you think about this: https://github.com/rvm/rvm/issues/3746#issuecomment-255589461 ?
I think this would work only if the command is run via a subshell that executes the rvm initialization function, wouldn’t it? And wouldn’t that have the same overhead as running rvm . do which …
?
I think this would work only if the command is run via a subshell that executes the rvm initialization function, wouldn’t it
Yes.
And wouldn’t that have the same overhead as running rvm . do which …?
Not sure. Sourcing RVM takes 18ms and navigating to a directory with a project file takes around 140ms.
But we would not need to manually check for the project files.
Back at this after 2 busy weeks: Regarding RVM, if we want to run the command via a subshell I think we’ll need to provide a tiny wrapper script (that does nothing more than cd $directory && $executable
). This is because I want #find_executable
to always return an array (makes it easier to append additional arguments, doesn’t need to spawn a subshell when used with system
, exec
, popen
etc.)
Should I give this a try? What would be the definitive way to initialize rvm in this wrapper script?
What would be the definitive way to initialize rvm in this wrapper script?
RVM adds the following to .bashrc
or similar:
export PATH="$PATH:$HOME/.rvm/bin" # Add RVM to PATH for scripting
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
I think that the last line is all that's needed.
Thanks for the quick response!
One more question: Will this work correctly if the working directory is alread set to the project directory? I.e. does cd .
work correctly with rvm? Or do we need some trickery like cd $(pwd)
?
I just implemented this (currently using cd .
in the wrapper script). @jacob-carlborg: Please let me know if this works for you!
Any news on this ( @jacob-carlborg, @sanssecours)?
(There’s a recent issue from my RuboCop bundle concerning RVM: https://github.com/noniq/RuboCop.tmbundle/issues/1 – would be perfect if I could fix that issue by making the RuboCop bundle use Executable.find
)
Any news on this ( @jacob-carlborg, @sanssecours)?
Basically I am just waiting for this pull request to get through, so I can add the Ruby version of “Reformat Code“.
The master branch of my clone of the Ruby bundle already uses the latest version of Executable.find
. In my experience – with “Reformat Document” – so far Executable.find
works just fine. However, as I already mentioned before, I do not use RVM at all.
There’s a recent issue from my RuboCop bundle…
Oh, another RuboCop bundle 😀. I think I will try that one too…
Overall I think it looks fine. I'll try tomorrow to actually test it to see that it works properly.
Most things seem to work, although I noticed two things that don't work:
/
is not allowed in the regular expression.
is not allowed in the regular expressionThe purpose of Executable.find
is to find a Ruby executable when you know the name only. If you already know / have a path, you don’t need this function at all, so not allowing /
in the name
argument is on purpose.
Ad 2.: Are there any valid Ruby executables with a .
in their name? I can’t think of any, but I’ll happily extend the regex if I’m proven wrong :-)
The purpose of Executable.find is to find a Ruby executable when you know the name only. If you already know / have a path, you don’t need this function at all, so not allowing / in the name argument is on purpose.
It would handle RVM automatically.
Ad 2.: Are there any valid Ruby executables with a . in their name? I can’t think of any, but I’ll happily extend the regex if I’m proven wrong :-)
I don't know, but I tried just executing a Ruby file (with the .rb
extension) and that failed.
I don't understand why you're insisting on adding artificial limitations.
I want this method to serve a precisely defined use-case: Finding ruby-installed executables like rspec, rubocop or kramdown. Nothing less, but nothing more neither (the code is already to complex for my taste, but I haven’t yet found a way to simplify it while keeping all the features that are necessary).
Remember that the original idea behind this PR was to provide this functionality as a service to other bundles. There are several bundles (eg. RSpec, various RuboCup ones, the Ruby bundle itself [see #99]) that would profit from using Executable.find
in exact the way it is now designed to be used.
If additional use cases show up in the future, we can of course change or extend this feature at any time. But for now I think we should get this finally merged, so that other bundles can start using it. Then we’ll see how it goes. 😀
Then I think this looks good 👌. Unfortunately I don't have permission to merge. @sorbits @infininight please have a look.
Gentle ping @sorbits @infininight :)
TL;DR: I don’t think you need to re-read all of the discussion here in detail. See #102 for the rationale behind the feature and this comment for an explanation of how it works and how to use it.
Most of the (loooooong) discussion here was around specific details of how to make this feature work with all kinds of setups people might use nowadays (rvm, rbenv, bundler, …). In the end we arrived at a nice (and well-tested) implementation.
I’m rather sure that there still are some cases we haven’t covered, but these will only start to turn up when this feature starts getting used. I’ll happily commit to continue supporting this feature in the future (as long as I’m still using TextMate, but no plans to change that for now 🙃).
Ping @infininight @sorbits (see above for the TL;DR 🙂)
Sorry about the delay, I have squashed all the commits into f49a2f5113745a0c88c29924329eb1ca896d0f9e and merged that, I hope this is acceptable.
Great, thanks!
First try on implementing #102. Not sure about the module name
RubyUtils
, though – happy to take suggestions for alternative names!TODO: Do we need to do something special to support RVM?