scriptcs / scriptcs

Write C# apps with a text editor, nuget and the power of Roslyn!
http://scriptcs.net
Other
2.46k stars 371 forks source link

Allow globally installed modules to add executables to PATH #571

Closed adamralph closed 10 years ago

adamralph commented 10 years ago

RubyGems has the ability to do this (see http://guides.rubygems.org/make-your-own-gem/#adding-an-executable). The best example is Rake. After installing the Rake gem, (it comes bundled with later versions of Ruby anyway) the bootstrapper files rake (shell script) and rake.bat are available on the path and they wrap up the calling of Ruby with the rake gem to give a much nicer command line interface.

I'm thinking of implementing Bau as a scriptcs module, which is something @filipw suggested, but I'd like to replicate the Rake command line so that in the simplest case, the user just types bau and this would wrap up something like scriptcs baufile.csx -modules bau and also translating any args passed to bau to script args.

I also want bau to search upwards from the current folder for a baufile.csx, as Rake does with rakefile.rb so the bootstrapper won't be as trivial as just forming the above command line. I may even end up still doing it as an exe (and a shell script for *nix to wrap the mono call if scriptcs mono gets off the ground).

It would also be good for the bootstrapper to be able to run a .csx local to itself too. I guess that would require module installation to be able bring along /content files. Is that something that will already happen through the use of NuGet.Core?

glennblock commented 10 years ago

Yes we want this. We talked about this early on. I had proposed we have a way to distribute scripts via nuget (kind of like script packs) and then have them installed locally potentially in the same place as global modules. Issue #238 relates.

My original thinking was you deploy one or more scripts in a nuget package so dependencies are handled. Then you have ONE path added to your main path. That path will have batch / shell scripts dropped into it (maybe during scriptcs -install -g) for each command which would then invoke the global script.

What was your thinking?

glennblock commented 10 years ago

The simplest path today though is probably just use chocolatey and have a batch file within that runs the script.

adamralph commented 10 years ago

I think you're right about having one path added to PATH. This is what Ruby does too. Typically a Ruby installation adds C:\bin\ruby200 to PATH and then gem installations add batch files, shell scripts, exe's etc. to that folder. It should definitely allow for multiple executables to be dropped in per installation to allow for multiple commands as you describe.

I also really like the idea of installing scripts globally. That's really got me thinking now about the mechanics of invoking Bau. I'm starting to think that I may even re-implement the whole thing in script instead of compiled assemblies. That would make a great scriptcs in the wild showcase!

It would be great if both module installation and script installation had this capability to drop executables into PATH. Is there a global installation option for script packs too?

I also considered the chocolatey route which would work today and actually that was my original plan with Bau.exe. It wouldn't even have a dependency on scriptcs installation since it would just use it's own local copies of the required scriptcs assemblies, but I think it would be much better for Bau to embrace as much of the scriptcs ecosystem as possible.

I'm quite excited about the notion of implementing Bau purely in scripts. It means that it wouldn't need to dive 'under the covers' of scriptcs and use the libs that constitute it. It would be a pure user API implementation (i.e. script execution) and in that way it would be way closer to the implementation of a typical Ruby or nodejs package. I'm not aware of anything significant which has been done in this way until now so it would be a great way to prove the concept and also drive out any required enhancements to scriptcs. Not to mention giving me some awesome material for my scriptcs in the wild talk :wink:.

glennblock commented 10 years ago

Well I really prefer we not go down the route of global script packs. I think we have node.js setting a really good precedent here of modules (script packs) being ONLY local and CLI tools / dependencies being global. This makes it really easy to just copy an app in it's entirety, as well as mitigating against version issues. I'll also add that having global anything is what has caused tons of pains in the .NET world, GAC anyone?

The one exception I'd say is that a CLI tool could depend on a script pack and that would be global BUT it would only be used by the CLI tool and NOT by user code.

On Mon, Feb 3, 2014 at 11:47 PM, Adam Ralph notifications@github.comwrote:

I think you're right about having one path added to PATH. This is what Ruby does too. Typically a Ruby installation adds C:\bin\ruby200 to PATH and then gem installations add batch files, shell scripts, exe's etc. to that folder. It should definitely allow for multiple executables to be dropped in per installation to allow for multiple commands as you describe.

I also really like the idea of installing scripts globally. That's really got me thinking now about the mechanics of invoking Bau. I'm starting to think that I may even re-implement the whole thing in script instead of compiled assemblies. That would make a great scriptcs in the wild showcase!

It would be great if both module installation and script installation had this capability to drop executables into PATH. Is there a global installation option for script packs too?

I also considered the chocolatey route which would work today and actually that was my original plan with Bau.exe. It wouldn't even have a dependency on scriptcs installation since it would just use it's own local copies of the required scriptcs assemblies, but I think it would be much better for Bau to embrace as much of the scriptcs ecosystem as possible.

I'm quite excited about the notion of implementing Bau purely in scripts. It means that it wouldn't need to dive 'under the covers' of scriptcs and use the libs that constitute it. It would be a pure user API implementation (i.e. script execution) and in that way it would be way closer to the implementation of a typical Ruby or nodejs package. I'm not aware of anything significant which has been done in this way until now so it would be a great way to prove the concept and also drive out any required enhancements to scriptcs. Not to mention giving me some awesome material for my scriptcs in the wild talk [image: :wink:].

Reply to this email directly or view it on GitHubhttps://github.com/scriptcs/scriptcs/issues/571#issuecomment-34037256 .

glennblock commented 10 years ago

Sorry I mean node sets a precedent that APPLICATION MODULES are only local / not global.

On Tue, Feb 4, 2014 at 2:00 AM, Glenn Block glenn.block@gmail.com wrote:

Well I really prefer we not go down the route of global script packs. I think we have node.js setting a really good precedent here of modules (script packs) being ONLY local and CLI tools / dependencies being global. This makes it really easy to just copy an app in it's entirety, as well as mitigating against version issues. I'll also add that having global anything is what has caused tons of pains in the .NET world, GAC anyone?

The one exception I'd say is that a CLI tool could depend on a script pack and that would be global BUT it would only be used by the CLI tool and NOT by user code.

On Mon, Feb 3, 2014 at 11:47 PM, Adam Ralph notifications@github.comwrote:

I think you're right about having one path added to PATH. This is what Ruby does too. Typically a Ruby installation adds C:\bin\ruby200 to PATH and then gem installations add batch files, shell scripts, exe's etc. to that folder. It should definitely allow for multiple executables to be dropped in per installation to allow for multiple commands as you describe.

I also really like the idea of installing scripts globally. That's really got me thinking now about the mechanics of invoking Bau. I'm starting to think that I may even re-implement the whole thing in script instead of compiled assemblies. That would make a great scriptcs in the wild showcase!

It would be great if both module installation and script installation had this capability to drop executables into PATH. Is there a global installation option for script packs too?

I also considered the chocolatey route which would work today and actually that was my original plan with Bau.exe. It wouldn't even have a dependency on scriptcs installation since it would just use it's own local copies of the required scriptcs assemblies, but I think it would be much better for Bau to embrace as much of the scriptcs ecosystem as possible.

I'm quite excited about the notion of implementing Bau purely in scripts. It means that it wouldn't need to dive 'under the covers' of scriptcs and use the libs that constitute it. It would be a pure user API implementation (i.e. script execution) and in that way it would be way closer to the implementation of a typical Ruby or nodejs package. I'm not aware of anything significant which has been done in this way until now so it would be a great way to prove the concept and also drive out any required enhancements to scriptcs. Not to mention giving me some awesome material for my scriptcs in the wild talk [image: :wink:].

Reply to this email directly or view it on GitHubhttps://github.com/scriptcs/scriptcs/issues/571#issuecomment-34037256 .

adamralph commented 10 years ago

OK, I'm not bothered about global script packs. That was just an incidental question.

So what is the idea with modules? Are they going to be kept global or will they become local?

I'm also generally against the idea of global anything and yes, I appreciate the pain of the GAC and have always steered clear of using it.

The only reason I'm keen to explore a global installation option of Bau is to replicate the excellent experience of using rake, i.e. you can be anywhere deep in the bowels of your source tree and you just type rake to rebuild. That will always require something in PATH.

I'm also definitely planning to have another distribution of Bau which only installs to your local project. I guess this will be just a regular NuGet tools package, possibly with a pre-rolled bau.bat which can be copied out to the root folder with a tweak to the path it uses if required.

glennblock commented 10 years ago

So my thinking is global script packs make sense for global CLI type commands. This is also what node does. For example if you install the azure-cli, which is a node cli, then all it's dependent modules are also installed globally, so for global CLI scripts, I'd imagine the same, thus this would support Bau.

In terms of modules, by design they are meant to be global. For example if I install a mono module, I shouldn't have to pull it in every time. The reason is because modules extend scriptcs itself, so scriptcs is the app in this case :-)

I don't see global modules going away. And I think the new CLI commands basically are script packs, but a special kind that would only really be installed globally.

Does that make sense?

adamralph commented 10 years ago

OK, yes that does make sense.

So assuming the local CLI command is a batch file, would it invoke a globally installed script which would in turn Require<T> a script pack? e.g.

REM bau.bat
@ECHO OFF
SET DIR=%~dp0%
CMD /c "scriptcs globalinstalllocation/bau.csx -- %*"
EXIT /b %ERRORLEVEL%
// bau.csx
var bau = Require<Bau>();
...

One tripping up point I can forsee is that Bau will have to search the working directory upwards for a baufile.csx and then execute it, but if it is already executing as a script, I can't do a dynamic #load half way through a script using a variable path. Or is there something in scriptcs which allow me to do something like that now?

glennblock commented 10 years ago

"So assuming the local CLI command is a batch file, would it invoke a globally installed script which would in turn Require a script pack? e.g."

It can work today as long as the packages are in the same folder as the script, it should be no different then running a plain old script.

"one tripping up point I can forsee is that Bau will have to search the working directory upwards for a baufile.csx and then execute it, but if it is already executing as a script, I can't do a dynamic #load half way through a script using a variable path."

You can by using scriptcs itself within the script i.e. you can create a script host, etc.

It is something we should think more about though, like should we make it easier for you to do this sort of thing, maybe allowing anyone to do a Require<ScriptCs>() (built in script pack) which allows them to grab a host (maybe the current host) and build a script so they can execute it.

adamralph commented 10 years ago

OK, so I've come round to the idea of global script packs and I can see that ultimately that will be a good installation option for Bau (as opposed to being a module), with local installation also still being an option. I've played a bit more with npm and I can see the parallels.

So it turns out what I'm really looking for here is 'Allow globally installed script packs to add executables to PATH'. Is there already an issue raised for global script packs which I can add to or should I alter the title and description of this issue?

glennblock commented 10 years ago

Having global script packs for CLI tools makes sense. Being able to support script packs that are used by non-global scriptcs however is not something I want to open up.

On Thursday, March 27, 2014, Adam Ralph notifications@github.com wrote:

OK, so I've come round to the idea of global script packs and I can see that ultimately that will be a good installation option for Bau (as opposed to being a module), with local installation also still being an option. I've played a bit more with npm and I can see the parallels.

So it turns out what I'm really looking for here is 'Allow globally installed script packs to add executables to PATH'. Is there already an issue raised for global script packs which I can add to or should I alter the title and description of this issue?

Reply to this email directly or view it on GitHubhttps://github.com/scriptcs/scriptcs/issues/571#issuecomment-38825037 .

glennblock commented 10 years ago

Meaning global script packs would similar to global modules in node. That is global node modules are used for CLI tools and their dependencies, but they are not loaded when one uses require in a script/module that is not global.

Is that what you were thinking?

On Thursday, March 27, 2014, Glenn Block glenn.block@gmail.com wrote:

Having global script packs for CLI tools makes sense. Being able to support script packs that are used by non-global scriptcs however is not something I want to open up.

On Thursday, March 27, 2014, Adam Ralph notifications@github.com<javascript:_e(%7B%7D,'cvml','notifications@github.com');> wrote:

OK, so I've come round to the idea of global script packs and I can see that ultimately that will be a good installation option for Bau (as opposed to being a module), with local installation also still being an option. I've played a bit more with npm and I can see the parallels.

So it turns out what I'm really looking for here is 'Allow globally installed script packs to add executables to PATH'. Is there already an issue raised for global script packs which I can add to or should I alter the title and description of this issue?

Reply to this email directly or view it on GitHubhttps://github.com/scriptcs/scriptcs/issues/571#issuecomment-38825037 .

adamralph commented 10 years ago

Yes, I'm thinking along the same lines now.

A tool like Bau can follow the pattern of Grunt, i.e. a Bau script pack which gets installed next to baufile.csx and a Bau.Cli global script pack which adds the bau command to the system path.

Closing this issue in favour of #607.

glennblock commented 10 years ago

Cool. I will implement this. I think we should follow node's lead and have a single path where batch / bash files get auto generated which are the cli tools.

On Sunday, March 30, 2014, Adam Ralph notifications@github.com wrote:

Yes, I'm thinking along the same lines now.

A tool like Bau can follow the pattern of Grunt, i.e. a Bau script pack which gets installed next to baufile.csx and a Bau.Cli global script pack which adds the bau command to the system path.

Closing this issue in favour of #607https://github.com/scriptcs/scriptcs/issues/607 .

Reply to this email directly or view it on GitHubhttps://github.com/scriptcs/scriptcs/issues/571#issuecomment-39027367 .