-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding header to generated JS (#1778) #1793
Conversation
I think the version number should be the first 10 hex digits of the commit hash when their version isn't tagged. So, we shouldn't be marking things as |
That's a very interesting suggestion, and I've wanted something like that for a while, but I'm not sure that it can be implemented in any way that wouldn't be Rube Goldberg-esque. Consider: You make a commit, which gets an ID. Now you want that ID to become part of the (committed) source. But if you do another commit, then that'll have a different ID. Even So, maybe I'm missing some git-jitsu, but the only way I see that working is if every ordinary commit were followed by a separate commit that changed the version. It's possible (you could have a |
@TrevorBurnham: I'm not talking about adding the commit identifier of the project (like, say, |
Right, I believe we're talking about the same thing. How would you go about making On Oct 22, 2011, at 5:26 PM, Michael [email protected] wrote:
|
I don't know what you mean. Why would |
As satyr might put it:
(Actually, on my system, Also, I don't see how
could possibly work if a Or maybe I still don't understand what you're suggesting? |
@TrevorBurnham: You must have missed the part of my comment that says we only look at the git commit identifier if the error code of |
@michaelficarra OK; I look forward to seeing your pull request, then. Incidentally, you might want to use
where 138 is the number of commits since the tagged version. Very helpful, IMHO. |
@TrevorBurnham: I just tried implementing my idea, but got stuck because we have a synchronous interface and node only has an asynchronous child process handling interface. We need to have both sync and async interfaces like node does. So here's what I came up with: diff --git a/src/coffee-script.coffee b/src/coffee-script.coffee
index df192a74..48ec2fd8 100644
--- a/src/coffee-script.coffee
+++ b/src/coffee-script.coffee
@@ -20,7 +20,8 @@ else if require.registerExtension
require.registerExtension '.coffee', (content) -> compile content
# The current CoffeeScript version number.
-exports.VERSION = '1.1.3-pre'
+VERSION = '1.1.3-pre'
+exports.VERSION = VERSION
# Words that cannot be used as identifiers in CoffeeScript code
exports.RESERVED = RESERVED
@@ -30,12 +31,44 @@ exports.helpers = require './helpers'
# Compile a string of CoffeeScript code to JavaScript, using the Coffee/Jison
# compiler.
-exports.compile = compile = (code, options = {}) ->
+exports.compile = compile = (code, options = {}, cb) ->
+ if typeof options is 'function' and !cb?
+ cb = options
+ options = {}
try
- (parser.parse lexer.tokenize code).compile options
+ js = (parser.parse lexer.tokenize code).compile options
catch err
err.message = "In #{options.filename}, #{err.message}" if options.filename
throw err
+ return cb?(js) unless options.header
+ spawn = require('child_process').spawn
+ version = VERSION
+ date = (new Date).toUTCString()
+ genHeader = ->
+ header = "Generated by CoffeeScript #{version} on #{date}"
+ cb? "// #{header}\n#{js}"
+ (spawn 'which', ['git']).on 'exit', (whichGitCode) ->
+ return genHeader() unless whichGitCode is 0
+ (spawn 'git', ['status']).on 'exit', (gitStatusCode) ->
+ return genHeader() unless gitStatusCode is 0
+ (spawn 'git', ['describe', '--tag', '--abbrev=10']).stdout.on 'data', (gitVersion) ->
+ version = gitVersion
+ genHeader()
+
+exports.compileSync = compileSync = (code, options = {}) ->
+ try
+ js = (parser.parse lexer.tokenize code).compile options
+ catch err
+ err.message = "In #{options.filename}, #{err.message}" if options.filename
+ throw err
+ return js unless options.header
+ version = VERSION
+ # if node provided a synchronous child process API, we could do something like this:
+ # if spawn('git status').code is 0
+ # version = spawn('git describe --tag --abbrev=10').stdout
+ date = (new Date).toUTCString()
+ header = "Generated by CoffeeScript #{version} on #{date}"
+ "// #{header}\n#{js}" I'll open an issue for adding an async API. |
@michaelficarra Is there a compelling use case for all this? You're proposing an expansion of the API just so that folks who use untagged versions to build their projects can see, from the top line of their JS files, exactly which commit was used to build them. Personally, I wouldn't have much use for this feature, because I only use untagged versions of CoffeeScript when participating in CoffeeScript issue discussions; when I'm building JS files, I'm using the latest release. So the header, as it exists in this pull request, is perfectly suited to my needs, and to the needs of anyone who only uses stable CoffeeScript versions for their projects. Adding headers with more precise version information seems neat, but if it can't be done in a more elegant way than spawning a process that only works if CoffeeScript was installed in a certain way (and obviously won't work at all in a browser environment), then it would seem more appropriate to create a separate tool for the job. |
@TrevorBurnham: I'm not saying this is a compelling reason to change the API. I'm saying the API should be changed anyway, and this feature depends on it being changed. It wouldn't be a big deal if we had had an async API already or if node provided a synchronous child process interface. edit: For now, I'd be okay with something like this: exports.compile = compile = (code, options = {}) ->
try
js = (parser.parse lexer.tokenize code).compile options
catch err
err.message = "In #{options.filename}, #{err.message}" if options.filename
throw err
return js unless options.header
version = VERSION
date = (new Date).toUTCString()
header = "Generated by CoffeeScript #{version} on #{date}"
"// #{header}\n#{js}" We obviously shouldn't wait on an API change to implement #1788. |
Hold off on merging this for the time being, if you don't mind -- I'm still fairly wary of adding a header to every file. We're already running into situations where it's not desirable. |
Sure thing. Awaiting your approval.
Are you referring to the
so it makes sense from a documentation standpoint that the other
Of course, the changing header would add some commit clutter, but that'd only happen when |
Returning to the original proposal: Have you had time to consider this, @jashkenas? Having
at the top of generated JS files would be helpful both to humans and to tools (like GitHub) that have good reason to treat generated JS differently than hand-coded JS. |
I think it sounds good. Want to fix this pull req to merge cleanly? |
Done. |
Uh, oh -- if you notice in the commit, this actually breaks Github's current auto-detection. Pinging @josh to take a look. |
@TrevorBurnham: consider using the code I posted above instead. That way, we get the date as well, and it's a little cleaner with the early exit. |
I don't think we want the date -- the relevant thing should be the version of the compiler used. |
I'd suggest to @josh that GitHub should suppress diffs on all JS files starting with @michaelficarra I agree with Jeremy that a date in the header is TMI. It'd result in a lot of unnecessary diffs, since |
@TrevorBurnham: I'm convinced. How about that early exist, though? It's a lot cleaner. |
A |
@TrevorBurnham: throw in the early return and feel free to merge. In general, let's never be reliant on the coercion of |
Adding header to generated JS (#1778)
Cool. Done and done. |
Awesome. This one has been a long time coming. |
The proposal at #1778 seemed to get a favorable reception. Here's an implementation. As discussed:
CoffeeScript.compile
function. It's disabled by default.coffee
command (-c
), but not to stdio output (e.g.-p
).Thoughts? Refinements?