`coffee dir` executes every coffee file, vs `node dir` which executes `index.js` only. #2496

Closed
leeola opened this Issue Aug 15, 2012 · 14 comments

Comments

Projects
None yet
7 participants
@leeola

leeola commented Aug 15, 2012

Well as the title says, if you run coffee directory CoffeeScript will "execute" every coffee file found within that directory, as if they were all called directly (coffee dir/foo.coffee, coffee dir/bar.coffee, etc). This is very different behavior from node directory which will look for, and only execute, an index.js file if found.

Is this a bug? Or working as intended?

Note that the work-around is not hard, simply execute the index file explicitly, such as: coffee directory/index.coffee, it just seems more logical that coffee dir and node dir should do the same things, as they do the same thing when used like coffee file and node file.

@leeola

This comment has been minimized.

Show comment
Hide comment
@leeola

leeola Aug 18, 2012

For example, with the following files..

# example/index.coffee
if require.main is module
  console.log 'Index is the main file run! I was run directly by the user!'

exports.file1 = require './file1'
exports.file2 = require './file2'
exports.file3 = require './file3' 

# example/file1.coffee
if require.main is module
  console.log 'File1 is the main file run! I was run directly by the user!'

# example/file2.coffee
if require.main is module
  console.log 'File2 is the main file run! I was run directly by the user!'

# example/file3.coffee
if require.main is module
  console.log 'File3 is the main file run! I was run directly by the user!'

And the actual output for this is...

File1 is the main file run! I was run directly by the user!
Index is the main file run! I was run directly by the user!
File3 is the main file run! I was run directly by the user!
File2 is the main file run! I was run directly by the user!

Now, i would expect the output to simply be:

Index is the main file run! I was run directly by the user!

The reason for this is simply that interpreters such as Node and Python have the expected behavior to execute a directory by executing the index file only. Coffee, on the other hand, executes every file in the directory.

I would think this would be counterintuitive to many of the new Coffee users coming from Nodejs.

Not a huge issue either way.

leeola commented Aug 18, 2012

For example, with the following files..

# example/index.coffee
if require.main is module
  console.log 'Index is the main file run! I was run directly by the user!'

exports.file1 = require './file1'
exports.file2 = require './file2'
exports.file3 = require './file3' 

# example/file1.coffee
if require.main is module
  console.log 'File1 is the main file run! I was run directly by the user!'

# example/file2.coffee
if require.main is module
  console.log 'File2 is the main file run! I was run directly by the user!'

# example/file3.coffee
if require.main is module
  console.log 'File3 is the main file run! I was run directly by the user!'

And the actual output for this is...

File1 is the main file run! I was run directly by the user!
Index is the main file run! I was run directly by the user!
File3 is the main file run! I was run directly by the user!
File2 is the main file run! I was run directly by the user!

Now, i would expect the output to simply be:

Index is the main file run! I was run directly by the user!

The reason for this is simply that interpreters such as Node and Python have the expected behavior to execute a directory by executing the index file only. Coffee, on the other hand, executes every file in the directory.

I would think this would be counterintuitive to many of the new Coffee users coming from Nodejs.

Not a huge issue either way.

@aseemk

This comment has been minimized.

Show comment
Hide comment
@aseemk

aseemk Aug 24, 2012

Contributor

I've wondered about this for a long time, too, and agree that unless there's a good reason for this (which there may be; just not aware of any), it'd be great for coffee foo to work just like node foo, even if foo is a directory.

The good news is that Node has the algorithm for this both documented and exposed:

http://nodejs.org/api/modules.html#modules_all_together
https://github.com/joyent/node/blob/v0.8.8/lib/module.js#L323 (Module._resolveFilename('foo'))

Contributor

aseemk commented Aug 24, 2012

I've wondered about this for a long time, too, and agree that unless there's a good reason for this (which there may be; just not aware of any), it'd be great for coffee foo to work just like node foo, even if foo is a directory.

The good news is that Node has the algorithm for this both documented and exposed:

http://nodejs.org/api/modules.html#modules_all_together
https://github.com/joyent/node/blob/v0.8.8/lib/module.js#L323 (Module._resolveFilename('foo'))

@mjadobson

This comment has been minimized.

Show comment
Hide comment
@mjadobson

mjadobson Aug 24, 2012

Yeah, I was thrown by this a little while back when I started playing with coffee-script. Definitely would be nice if it worked the same as node.

Yeah, I was thrown by this a little while back when I started playing with coffee-script. Definitely would be nice if it worked the same as node.

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Feb 11, 2013

I would imagine it's in there for tests - you can have all your tests in separate files in a "test" directory, and run them all by doing

coffee test

Rather than having to write an index file that loads in and runs each test individually.

ghost commented Feb 11, 2013

I would imagine it's in there for tests - you can have all your tests in separate files in a "test" directory, and run them all by doing

coffee test

Rather than having to write an index file that loads in and runs each test individually.

@vendethiel

This comment has been minimized.

Show comment
Hide comment
@vendethiel

vendethiel Feb 11, 2013

Collaborator

You need helpers etc for test suites anyway, so I hardly see how that could be the case

Collaborator

vendethiel commented Feb 11, 2013

You need helpers etc for test suites anyway, so I hardly see how that could be the case

@ghost

This comment has been minimized.

Show comment
Hide comment
@ghost

ghost Feb 11, 2013

What do you mean? vows, for one, can run a file with tests in it straight through node or coffee.

ghost commented Feb 11, 2013

What do you mean? vows, for one, can run a file with tests in it straight through node or coffee.

@vendethiel

This comment has been minimized.

Show comment
Hide comment
@vendethiel

vendethiel Feb 11, 2013

Collaborator

oh that's definitely nice

Collaborator

vendethiel commented Feb 11, 2013

oh that's definitely nice

@jashkenas

This comment has been minimized.

Show comment
Hide comment
@jashkenas

jashkenas Mar 4, 2013

Owner

Hrm... If we changed this, then the behavior of coffee dir would vastly differ from the behavior of coffee --compile dir. Is that acceptable? @michaelficarra, how have you solved this?

Owner

jashkenas commented Mar 4, 2013

Hrm... If we changed this, then the behavior of coffee dir would vastly differ from the behavior of coffee --compile dir. Is that acceptable? @michaelficarra, how have you solved this?

@michaelficarra

This comment has been minimized.

Show comment
Hide comment
@michaelficarra

michaelficarra Mar 4, 2013

Collaborator

My CLI simply behaves as node's. The relevant issue is already linked above: michaelficarra/CoffeeScriptRedux#102

Collaborator

michaelficarra commented Mar 4, 2013

My CLI simply behaves as node's. The relevant issue is already linked above: michaelficarra/CoffeeScriptRedux#102

@ppvg

This comment has been minimized.

Show comment
Hide comment
@ppvg

ppvg Mar 27, 2013

Calling coffee on a directory also seriously messes up the require chain:

  • sometimes (but not always!) a module will be its own parent
  • parent/child relationships between files in the directory are not reflected in the module objects (neither module.parent nor module.children)

Is there a reliable way to tell whether the process was started by calling coffee ./dir, as opposed to coffee ./dir/file.coffee?

ppvg commented Mar 27, 2013

Calling coffee on a directory also seriously messes up the require chain:

  • sometimes (but not always!) a module will be its own parent
  • parent/child relationships between files in the directory are not reflected in the module objects (neither module.parent nor module.children)

Is there a reliable way to tell whether the process was started by calling coffee ./dir, as opposed to coffee ./dir/file.coffee?

@leeola

This comment has been minimized.

Show comment
Hide comment
@leeola

leeola Mar 27, 2013

@ppvg require.main should be how it's done, imo. If coffee is set to execute, it is essentially node and should behave in the same manner.

Either way, this may be a none issue anymore, since Redux handles the issue properly.

leeola commented Mar 27, 2013

@ppvg require.main should be how it's done, imo. If coffee is set to execute, it is essentially node and should behave in the same manner.

Either way, this may be a none issue anymore, since Redux handles the issue properly.

@ppvg

This comment has been minimized.

Show comment
Hide comment
@ppvg

ppvg Mar 27, 2013

@leeolayvar that's what I thought, but I don't think that's true. The result is identical when coffee is called on a directory, expect it seems to pick one of the directory's .coffee files at random to be require.main.

Since I'm writing a library, I can't depend on the users using either regular CS or CS Redux.

Edit:
I've ended up throwing an Error if there's any module with a cyclic dependency (where module.parent.filename equals module.filename). This happens most of the time (but not always), so at least I can warn the user that something's wrong.

ppvg commented Mar 27, 2013

@leeolayvar that's what I thought, but I don't think that's true. The result is identical when coffee is called on a directory, expect it seems to pick one of the directory's .coffee files at random to be require.main.

Since I'm writing a library, I can't depend on the users using either regular CS or CS Redux.

Edit:
I've ended up throwing an Error if there's any module with a cyclic dependency (where module.parent.filename equals module.filename). This happens most of the time (but not always), so at least I can warn the user that something's wrong.

@leeola

This comment has been minimized.

Show comment
Hide comment
@leeola

leeola Mar 30, 2013

@ppvg No, i mean that in my opinion, require.main should be how it works in coffee, but currently does not. Redux supposedly fixes this though, so it may be a nonissue.

leeola commented Mar 30, 2013

@ppvg No, i mean that in my opinion, require.main should be how it works in coffee, but currently does not. Redux supposedly fixes this though, so it may be a nonissue.

@aseemk

This comment has been minimized.

Show comment
Hide comment
@aseemk

aseemk Dec 31, 2013

Contributor

I noted this in #3292, but noting here too: it'd still be worth getting to full node parity by respecting the directory's package.json main field, if there is one. I believe require('module')._resolveFilename(path) gets you this.

Contributor

aseemk commented Dec 31, 2013

I noted this in #3292, but noting here too: it'd still be worth getting to full node parity by respecting the directory's package.json main field, if there is one. I believe require('module')._resolveFilename(path) gets you this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment