azproduction / lmd

LMD - JavaScript Module-Assembler for building better web applications :warning: Project is no longer supported :warning:
http://azproduction.ru/lmd/
MIT License
449 stars 27 forks source link

Setting to include LMD license into output #167

Closed leonidborisenko closed 10 years ago

leonidborisenko commented 10 years ago

Configuration setting is named 'lmd_license_header' and could be set to true.

License is prepended to output as multiline comment with '/*!' starting token (so that it could be bypassed by minifiers).

leonidborisenko commented 10 years ago

Travis CI build is failed because of incompatible (?) interface of new Vow version. Tests are passed locally with Vow 0.3.12.

azproduction commented 10 years ago

Hi! Thank your for this PR. Don't you think that grunt-banner can do exact the same thing? In my opinion, this is rare case and this option should be excluded or be more generalized.

LMD prepends // This file was automatically generated from "index.lmd.json" banner to each file.

Instead of creating lmd_license_header-option we can create banner(common name for that header) with default value:

// This file was automatically generated from "<%= config_basename %>"

This is underscore-style template. We can pass some variables to that file like config_basename, config_file and "compiled" config object.

In your config.lmd.js file you can define your own banner:

var read = require('fs').readFileSync;

var banner = '/*!\n  * ' + read('../LICENCE').replace(/\n/g, '\n  * ') + '\n  */';

module.exports = {
    banner: banner,
    modules: {
        ...
    }
};
leonidborisenko commented 10 years ago

Prepending banner to combined file after LMD wrote it to disk will break source map (because lines will be shifted), right? I didn't check it, but thinking logically, it should be the case.

So grunt-banner wouldn't help much.

I like idea of generalized banner option. However, example of its usage in my case isn't quite right. Here is a proper version.

var read = require('fs').readFileSync;

var banner = '/*!\n  * ' + read('../node_modules/lmd/LICENCE').replace(/\n/g, '\n  * ') + '\n  */';

module.exports = {
    banner: banner,
    modules: {
        ...
    }
};

Because I want to prepend LMD license.

So it would be nice to have variable lmd_loader_license accessible from template, so that knowledge of LMD license file placement and license structure wouldn't leak to LMD users. In other words I want to make a banner with something like:

{
  "root": "..",
  "banner": "/*! LMD loader and its stock plugins:\n<%= lmd_loader_license %>\n*/",
  "modules": {
    "example": "example.js"
  }
}

So if banner idea will win, please close this PR. I will open new issue and (maybe) make new PR.

azproduction commented 10 years ago

http://lmdjs.org/LICENCE instead of lmd_loader_license ;) Actually I can not prepend this licence because script bundle contains other code except mine.

leonidborisenko commented 10 years ago

http://lmdjs.org/LICENCE instead of lmd_loader_license ;)

I'm actually mystified by this sentence (no offence assumed). Is it a suggested template variable name?

Actually I can not prepend this licence because script bundle contains other code except mine.

Is it hard to include their names into copyright notice? Or did they not license their contribution under MIT license?

Let me describe my case in more details.

I'm trying to build HTML/CSS/JS-based app to execute in some WebKit-based environment extended with internal JS API. All app files will be placed in local filesystem and there will be no HTTP requests. So it makes sense to embed everything (CSS, minified JS, images as data URLs) into single HTML file and distribute this HTML file only. So there will be no additional files in distribution: no READMEs, no LICENSEs -- just one HTML file.

But MIT license requires distributing its text with copies/substantial portions of software. So by using and distributing LMD loader (which, I suppose, is licensed under MIT) I should include MIT license text into that HTML file. Right now I'm doing it manually. I copied LICENCE file from LMD repository into my project and prepend it by myself to minified output of LMD builder on building release flavor (i.e. distributed HTML file). Development flavor is built without prepending of license banner because I don't want to fix source map.

However, it means that I must to track changes in LMD loader license to make appropriate changes in my local copy. Furthemore, LMD's LICENCE file includes licenses of components which are used in Node.JS-based builder, but not relevant to small LMD loader (and stock plugins) that are included into HTML file and distributed. So I must also track these component's licenses and remove them from my local LMD's LICENCE.

I want to move this routine into LMD itself and abstract it by providing appropriate setting. This PR (as an attempt to implement routine) takes license straight from LICENCE file (so its text is actual) and strips part that's not relevant to loader.

Note that I'm interested only in license of loader (and stock plugins), which is executed in browser (those 288 bytes or about that). License of LMD builder and other files executed in Node.JS environment isn't a subject here.

So this leaves one important question. If (as you wrote) "script bundle contains other code except mine", then what license of LMD loader should I use for now, manually?

azproduction commented 10 years ago

contains other code except mine

Its about assembled modules.

Let me describe my case in more details.

Oh, do not worry about license stuff. Even mail.ru nor yandex don't care about that. And if you want to include LICENCE, you can embed it into HTML file.

And if you really want to embed it into .js file, then implementing "banner" is only good solution for that case.

PS I don't want to slow down implementing of this feature, I just want to make it better ;)

read(require.resolve('lmd/LICENCE'))
leonidborisenko commented 10 years ago

contains other code except mine Its about assembled modules.

OK, I think, I understand it now. You are saying that, in general case, LMD loader license automatically prepended as banner to whole assembled JS file can lead to wrong user's belief in getting the same license for all of assembled modules -- and this is certainly not the case. I do agree.

I solved this problem by adding license banners to all vendor libraries (assembled by LMD) and including names of libraries into that banners to clarify license scope.

BTW (as sidenote), jQuery distribution file already has license banner (with included library name).

Oh, do not worry about license stuff. Even mail.ru nor yandex don't care about that.

And if you want to include LICENCE, you can embed it into HTML file.

I don't worry so much about legal stuff. But I do worry about the same wrong user assumption that was just described a bit earlier. Say, I want to license my work (whole HTML) under some permissive license, but not MIT. I will include license banner with copyright notice to HTML file (I'm still speaking about whole HTML, not just JS part), Then user may mistakenly think that JS part (including LMD loader) also have the same license and I have copyright for LMD loader. I want to avoid this.

For example:

<!doctype html>
<!-- This file is licensed under WTFPL. Copyright 2014 John Doe. -->
<head>
  <script>
    /* Minimized JS that is licensed under MIT and have other copyright holder,
       but user doesn't know about this, because there is no banner by default.

       I can easily add banner for each vendor JS (including LMD loader) manually
       in release file, but I don't want to repeat this work again and again, so I
       want to see banner in every vendor JS (including LMD loader) by default or
       as an option.

      And without banner user will assume that I have copyright for this JS. */
    function a(){var s,i,ll,y,_,e,x,a,m,p,le;};
  </script>
</head>
<body>
</body>
</html>

Mail.ru and Yandex (in your examples) didn't include any license text in whole files, so they don't have this problem

And if you really want to embed it into .js file, then implementing "banner" is only good solution for that case.

PS I don't want to slow down implementing of this feature, I just want to make it better ;) read(require.resolve('lmd/LICENCE'))

I want an option to prepend LMD loader license to assembled JS file. In my case, this file then will be read and embedded in release HTML by instantiating of HTML template.

Are you thinking about implementing this feature by yourself? If so, I'm not in hurry and I can wait before your idea will be finally formed.

azproduction commented 10 years ago

Well, then "banner" is the only way. I close this PR and open an issue #168.

azproduction commented 10 years ago

Fixed in lmd@1.11.1. See example. And if you use read(require.resolve('lmd/LICENCE'), 'utf8') it will fit your needs.

leonidborisenko commented 10 years ago

Just for the record, here is a slightly modified code from previous comments (and from #168 also) which suits my needs expressed in this issue:

var fs = require('fs');

var licence = fs.readFileSync(require.resolve('lmd/LICENCE'), 'utf8');
var banner =
  '/*! LMD: ' +
  // Transform licence by adding ' *' after each newline.
  licence.replace(/\r\n(.?)/g, function (match, p1) {
    var newSubStr = '\n *';
    // Separate '*' mark and following character (if any) with space.
    if (p1) {
      newSubStr += (' ' + p1);
    }
    return newSubStr;
  }) + '/';

module.exports = {
  // <...>
  banner: banner
  // <...>
}

It produces following banner:

/*! LMD: (The MIT License)
 *
 * Copyright (c) 2011 Mikhail Davydov <i@azproduction.ru>
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * 'Software'), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
(function (global, main, modules, modules_options, options) {