jakejs / jake

JavaScript build tool, similar to Make or Rake. Built to work with Node.js.
http://jakejs.com
Apache License 2.0
1.97k stars 190 forks source link

Include .jake files from a submodule #234

Open joshleaves opened 10 years ago

joshleaves commented 10 years ago

I'm building a Node.js micro-framework and wanted to add a "rake routes"-like utility using Jake. Unfortunately, such a script would have to be included within my module.

Having to use a script or any other binary to include it in jakelib from somewhere else would just be counter-productive to the "micro-framework". I built a quick test to see if jake would check the node_modules subfolder in search of jakefiles:

 testjake $ tree
.
├── Jakefile
├── jakelib
│   └── libs.jake
└── node_modules
    └── another_lib
        └── jakelib
            └── other_libs.jake

4 directories, 3 files
testjake $

Here is the current behaviour:

testjake $ jake -T
jake default            # Jakefile: Default task
jake libsfunction       # jakelib/libs.jake: Default task
testjake $

Nope, no such luck :) And I don't want to add manually the jakelib for all folders I may need everytime I type "jake".

So the proposed behaviour for this new feature would be the following:

testjake $ jake -T
jake default                      # Jakefile: Default task
jake libsfunction                 # jakelib/libs.jake: Lib task
jake another_module:default       # Jakefile: Default task (from module another_module)
jake another_module:libsfunction  # jakelibs/libs.jake: Lib task (from module another_module)
testjake $

Of course, to avoid method overwrite by modules, all modules tasks are namespaced to the module name.

Some discussion about this feature before I start diving in it:

What do you think?

mde commented 10 years ago

This sounds like a really helpful thing to be able to do. It sounds like with the -R flag, it would be opt-in at the invocation step. But it sounds like it's opt-out at the module/structure level -- in other words, unless people set 'inheritable' to false, their tasks will show up in the jake -T -R list.

Right now, Jake assumes it's being invoked somewhere inside a project that's using Jake (it will look upward for Jakefiles). I'm wondering if there's a nice way to accomplish what you're wanting without completely nullifying this assumption.

Are you saying that apps using your microframework would be expected to be able to call this routes command without even having a Jakefile of their own?

joshleaves commented 10 years ago

Basically, this would remove the need for global binaries when they are not needed outside of a project. For example, express uses express -sec to generate a basic project structure but I need to install it globally to use it (which I sometimes can't/don't want to install globally, etc...).

With this, the tasks would be fetched from express's jakelib folder (provided I installed it for this project) and I could just run something jake -R express:generate engine=ejs.

The real benefit is that all scripts related to a project are tied to said project folder. Example case:

$ cat package.json | grep -A 3 dependencies
    "dependencies": {
    "express": "3.0.0", // Install globally to use!!!
    "uglifyjs": "~0.8.3", // Install globally to use!!!
    "sass": "~0.9.10", // Install globally to use!!!
$ cat Jakefile
cat: Jakefile: No such file or directory
$ npm install
// express, uglifyjs, sass are installed locally
$ jake -RT
express:generate  # Generate project structure (from express)
uglifyjs:default  # Uglify .js files in folder (from uglifyjs)
sass:default      # Convert .sass files to .css (from sass)
$ jake -R express:generate engine=ejs
$ jake -R uglifyjs:default folder=assets/js
$ jake -R sass:default folder=assets/css

Now I don't have my PATH filled with binaries I didn't need for things other than this project.

(Now of course the modules need to play the game too :D )

navneetgarg123 commented 7 years ago

It would probably make more sense to just add a require line into the Jakefile to load the tasks that would programmatically the load the tasks for that module.

How we do that is up to debate.

Either way the objective would be to load all of the tasks defined for that project. However, the first option puts the onus on the calling module to define its namespace. The second option could put the onus on either jake or the calling module.

navneetgarg123 commented 7 years ago

I've pushed up a possible implementation of this for

It hasn't been wired up with the command line yet thought. I've linked the commits below

sub module require recursive require