Browse Source

Merge branch 'grunt-init'

Herby Vojčík 5 years ago
parent
commit
2bb462f485

+ 22 - 0
grunt-init-project/LICENSE

@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (C) 2013 Manfred Kröhnert
+Copyright (C) 2014-2017 Amber contributors [amber/amber CONTRIBUTORS]
+
+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.

+ 33 - 0
grunt-init-project/README.md

@@ -0,0 +1,33 @@
+# [Amber Smalltalk](http://amber-lang.net) application generator.
+
+The intention of this tool is to automate the creation of Amber projects.
+This tool is based on [grunt-init](http://gruntjs.com/project-scaffolding).
+
+It is conveniently integrated into the `@ambers/cli` commandline tool, which should be preferred over using this project directly with `grunt-init`.
+
+Installation and initial getting started instructions can be found [here](https://www.npmjs.com/package/amber#getting-amber).
+
+
+#### Read on if you insist on doing it the [grunt-init](http://gruntjs.com/project-scaffolding) way
+
+Please note that `@ambers/cli` performs some additional project creation steps which you will be missing if you continue this way.
+
+Install [grunt-init](http://gruntjs.com/project-scaffolding) if you have not already done so.
+
+Place this template in your `~/.grunt-init/` directory using the following command:
+
+```
+git clone git://lolg.it/amber/grunt-init-amber.git ~/.grunt-init/amber
+```
+
+_Windows users, see [the grunt-init documentation](http://gruntjs.com/project-scaffolding) for the correct directory destination_
+
+
+At the command-line, change into an empty directory, run this command and follow the prompts.
+
+```
+grunt-init amber
+```
+
+_Note: this template will generate files in the current directory,
+so be sure to change to a new directory first if you do not want to overwrite existing files._

+ 17 - 0
grunt-init-project/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "@ambers/grunt-init-amber-project",
+  "version": "0.22.0",
+  "description": "grunt-init template for amber project",
+  "main": "template.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "https://lolg.it/amber/grunt-init-amber.git"
+  },
+  "license": "MIT",
+  "bugs": {
+    "url": "https://lolg.it/amber/grunt-init-amber/issues"
+  }
+}

+ 6 - 0
grunt-init-project/rename.json

@@ -0,0 +1,6 @@
+{
+  "gitignore-file": ".gitignore",
+  "localamdjson-file": "local.amd.json",
+  "src/name.st": "src/{%= name %}.st",
+  "src/test.st": "src/{%= name %}-Tests.st"
+}

+ 122 - 0
grunt-init-project/root/Gruntfile.js

@@ -0,0 +1,122 @@
+'use strict';
+
+module.exports = function (grunt) {
+    // These plugins provide necessary tasks.
+    grunt.loadNpmTasks('grunt-contrib-clean');
+    grunt.loadNpmTasks('grunt-contrib-requirejs');
+    grunt.loadNpmTasks('grunt-exec');
+    grunt.loadNpmTasks('@ambers/sdk');
+
+    var path = require('path'),
+        helpers = require('@ambers/sdk').helpers;
+
+    // Default task.
+    grunt.registerTask('default', ['amdconfig:app', 'amberc:all']);
+    grunt.registerTask('test', ['amdconfig:app', 'requirejs:test_runner', 'exec:test_runner', 'clean:test_runner']);
+    grunt.registerTask('devel', ['amdconfig:app', 'requirejs:devel']);
+    grunt.registerTask('deploy', ['amdconfig:app', 'requirejs:deploy']);
+
+    var polyfillThenPromiseApp = function () {
+        define(["require", "amber/es2015-polyfills"], function (require) {
+            return new Promise(function (resolve, reject) {
+                require(["__app__"], resolve, reject);
+            });
+        });
+    };
+
+    // Project configuration.
+    grunt.initConfig({
+        // Metadata.
+        // pkg: grunt.file.readJSON('{%= amberjson %}'),
+        banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
+        '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
+        '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
+        '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
+        ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
+        // task configuration
+        amberc: {
+            options: {
+                amber_dir: path.join(__dirname, "bower_components", "amber"),
+                configFile: "config.js"
+            },
+            all: {
+                src: [
+                    'src/{%= name %}.st', // list all sources in dependency order
+                    'src/{%= name %}-Tests.st' // list all tests in dependency order
+                ],
+                amd_namespace: '{%= namespace %}',
+                libraries: ['amber_core/SUnit', 'amber/web/Web', 'silk/Silk']
+            }
+        },
+
+        amdconfig: {app: {dest: 'config.js'}},
+
+        requirejs: {
+            options: {
+                useStrict: true
+            },
+            deploy: {
+                options: {
+                    mainConfigFile: "config.js",
+                    rawText: {
+                        "app": '(' + polyfillThenPromiseApp + '());',
+                        "__app__": 'define(["deploy", "amber_core/Platform-Browser"],function(x){return x});'
+                    },
+                    pragmas: {
+                        excludeIdeData: true,
+                        excludeDebugContexts: true
+                    },
+                    include: ['config', 'node_modules/requirejs/require', 'app', 'amber/lazypack', '__app__'],
+                    optimize: "uglify2",
+                    out: "the.js"
+                }
+            },
+            devel: {
+                options: {
+                    mainConfigFile: "config.js",
+                    rawText: {
+                        "app": '(' + polyfillThenPromiseApp + '());',
+                        "__app__": 'define(["devel", "amber_core/Platform-Browser"],function(x){return x});'
+                    },
+                    include: ['config', 'node_modules/requirejs/require', 'app', '__app__'],
+                    exclude: ['devel'],
+                    out: "the.js"
+                }
+            },
+            test_runner: {
+                options: {
+                    mainConfigFile: "config.js",
+                    rawText: {
+                        "jquery": "/* do not load in node test runner */",
+                        "__app__": "(" + function () {
+                            define(["testing", "amber_core/Platform-Node", "amber_devkit/NodeTestRunner"], function (amber) {
+                                amber.initialize().then(function () {
+                                    amber.globals.NodeTestRunner._main();
+                                });
+                            });
+                        } + "());",
+                        "app": "(" + polyfillThenPromiseApp + "());"
+                    },
+                    paths: {"amber_devkit": helpers.libPath},
+                    pragmas: {
+                        excludeIdeData: true
+                    },
+                    include: ['app', 'amber/lazypack', '__app__'],
+                    insertRequire: ['app'],
+                    optimize: "none",
+                    wrap: helpers.nodeWrapperWithShebang,
+                    out: "test_runner.js"
+                }
+            }
+        },
+
+        exec: {
+            test_runner: 'node test_runner.js'
+        },
+
+        clean: {
+            test_runner: ['test_runner.js']
+        }
+    });
+
+};

+ 40 - 0
grunt-init-project/root/README.md

@@ -0,0 +1,40 @@
+# {%= title || name %}
+
+{%= description %}
+
+## Getting Started
+
+Install Amber and create an Amber project,
+as shown in [Amber Instructions](https://lolg.it/amber/amber#prerequisites).
+
+## Use {%= name %} as a library in a client project
+
+If not already present, create a client project
+in an empty directory with `amber init`.
+
+In a client project, run
+
+```sh
+bower install {%= name %} --save
+grunt devel
+amber serve
+```
+
+Go to `http://localhost:4000/` in your browser and
+in all packages that use {%= name %},
+add `'{%= namespace %}/{%= name %}'` to the package imports,
+save the change and commit the package. Reload.
+
+## Contributing
+
+To bring project alive (for example after `git clone`):
+
+```sh
+npm install
+bower install
+grunt devel
+```
+
+Developing the project (after brought alive):
+ 
+Start server with `amber serve` and go to `http://localhost:4000/` in your browser and follow the instructions

+ 8 - 0
grunt-init-project/root/deploy.js

@@ -0,0 +1,8 @@
+define([
+    'amber/deploy',
+    // --- packages to be deployed begin here ---
+    '{%= namespace %}/{%= name %}'
+    // --- packages to be deployed end here ---
+], function (amber) {
+    return amber;
+});

+ 11 - 0
grunt-init-project/root/devel.js

@@ -0,0 +1,11 @@
+define([
+    './testing',
+    'amber/devel',
+    // --- packages used only during development begin here ---
+    'amber/legacy/Benchfib',
+    'amber/legacy/Examples',
+    'amber/legacy/IDE'
+    // --- packages used only during development end here ---
+], function (amber) {
+    return amber;
+});

+ 7 - 0
grunt-init-project/root/gitignore-file

@@ -0,0 +1,7 @@
+/node_modules/
+/bower_components/
+
+/test_runner.js
+
+/config.js
+/the.js

+ 41 - 0
grunt-init-project/root/index.html

@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <title>{%= title %}</title>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+    <meta name="author" content="{%= author_name %}"/>
+    <script type='text/javascript' src='the.js'></script>
+</head>
+
+<body>
+<!-- EXAMPLE APP START -->
+<p>This is a sample app. It contains some
+    <a href="parts.html">batteries included</a>
+    and should be
+    <a href="uninstall.html">cleaned up</a>
+    once you start developing your own app / lib.</p>
+<button id="amber-with">Hello from TagBrush >> with:</button>
+<button id="silk-tag">Hello from Silk >> TAG:</button>
+<button id="jquery-append">Hello from jQuery append</button>
+<ol id="output-list"></ol>
+<!-- EXAMPLE APP END -->
+<script type='text/javascript'>
+    var global = typeof global === "undefined" ? window : global || window;
+    require(['app'], function (amberPromise) {
+        amberPromise.then(function (amber) {
+            amber.initialize({
+                //used for all new packages in IDE
+                'transport.defaultAmdNamespace': "{%= namespace %}"
+            }).then(function () {
+                require(["amber-ide-starter-dialog"], function (dlg) {
+                    dlg.start();
+                });
+                amber.globals.{%= name %}._start();
+            });
+        });
+    });
+</script>
+</body>
+
+</html>

+ 5 - 0
grunt-init-project/root/localamdjson-file

@@ -0,0 +1,5 @@
+{
+    "paths": {
+        "{%= namespace %}": "src"
+    }
+}

+ 34 - 0
grunt-init-project/root/parts.html

@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+
+  <head>
+    <title>{%= title %}</title>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+    <meta name="author" content="{%= author_name %}" />
+  </head>
+
+  <body>
+  <p>The sample app contains three additional parts beyond Amber itself:</p>
+  <ul style="width: 40ex">
+      <li>The elements in <code>index.html</code>
+          <code>&lt;body&gt;</code> tag.</li>
+      <li><code>amber-contrib-jquery</code> module,
+          providing jQuery and a wrapper over it.</li>
+      <li><code>amber-contrib-web</code> module,
+          providing <code>Web</code> package
+          that allows for DOM manipulation
+          and is inspired by Seaside.</li>
+      <li><code>domite</code> module,
+          providing Amber-native DOM wrapper.</li>
+      <li><code>silk</code> module,
+          providing <code>Silk</code> package
+          that allows for DOM manipulation,
+          is meant as alternative to <code>Web</code>
+          and is inspired by stream metaphor and mochikit.</li>
+  </ul>
+  <p>Additionally, module <code>amber-compat-es2015</code>
+  is included by default. This polyfills JS Promise for non-modern
+  browsers / old node.js.</p>
+  </body>
+
+</html>

+ 36 - 0
grunt-init-project/root/src/name.st

@@ -0,0 +1,36 @@
+Smalltalk createPackage: '{%= name %}'!
+(Smalltalk packageAt: '{%= name %}' ifAbsent: [ self error: 'Package not created: {%= name %}' ]) imports: {'amber/jquery/Wrappers-JQuery'. 'amber/web/Web'. 'silk/Silk'}!
+Object subclass: #{%= name %}
+	instanceVariableNames: ''
+	package: '{%= name %}'!
+
+!{%= name %} methodsFor: 'action'!
+
+doAmberWith
+	| tag |
+	tag := (HTMLCanvas onJQuery: '#output-list' asJQuery) root.
+	tag with: [ :html | html li with: 'Amber Web #with: added me!!' ]
+!
+
+doJQueryAppend
+	'#output-list' asJQuery append: '<li>jQuery append added me!!</li>'
+!
+
+doSilkTAG
+	'#output-list' asSilk LI: 'Silk TAG: added me!!'
+! !
+
+!{%= name %} methodsFor: 'starting'!
+
+augmentPage
+	'#amber-with' asJQuery click: [ self doAmberWith ].
+	'#silk-tag' asSilk on: #click bind: [ self doSilkTAG ].
+	'#jquery-append' asJQuery click: [ self doJQueryAppend ]
+! !
+
+!{%= name %} class methodsFor: 'starting'!
+
+start
+	self new augmentPage
+! !
+

+ 5 - 0
grunt-init-project/root/src/test.st

@@ -0,0 +1,5 @@
+Smalltalk createPackage: '{%= name %}-Tests'!
+TestCase subclass: #{%= name %}Test
+	instanceVariableNames: ''
+	package: '{%= name %}-Tests'!
+

+ 9 - 0
grunt-init-project/root/testing.js

@@ -0,0 +1,9 @@
+define([
+    './deploy',
+    'amber_core/SUnit',
+    // --- packages used only during automated testing begin here ---
+    '{%= namespace %}/{%= name %}-Tests'
+    // --- packages used only during automated testing end here ---
+], function (amber) {
+    return amber;
+});

+ 57 - 0
grunt-init-project/root/uninstall.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+
+  <head>
+    <title>{%= title %}</title>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+    <meta name="author" content="{%= author_name %}" />
+  </head>
+
+  <body>
+  <p>Once you start developing your own app / lib, you should
+      remove all unnecessary parts left from the sample app.</p>
+  <ul style="width: 40ex">
+      <li>In <code>index.html</code>
+          <code>&lt;body&gt;</code> tag,
+          everything should be removed, except
+          the <code>&lt;script&gt;</code> tag
+          that initializes Amber and starts your app;
+          then you can add elements specific to your own app
+          to the page.</li>
+      <li>If you aren't going to use <code>Web</code>
+          package from <code>amber-contrib-web</code> module,
+          but want to retain the jQuery wrapper,
+          you should run <code>bower uninstall amber-contrib-web --save</code>
+          from your CLI.</li>
+      <li>If you aren't going to use the <code>Web</code>
+          package from the <code>amber-contrib-web</code> module,
+          nor the jQuery wrapper from <code>amber-contrib-jquery</code>,
+          you should run <code>bower uninstall amber-contrib-web amber-contrib-jquery --save</code>
+          from your CLI.</li>
+      <li>You cannot remove just the jQuery wrapper and retain the Web package,
+          as it depends on the jQuery wrapper.</li>
+      <li>If you aren't going to use <code>Silk</code>
+          package from <code>silk</code> module,
+          but want to retain <code>DOMite</code> DOM wrapper,
+          you should run <code>bower uninstall silk --save</code>
+          from your CLI.</li>
+      <li>If you aren't going to use the <code>Silk</code>
+          package from the <code>silk</code> module,
+          nor the DOM wrapper from <code>domite</code>,
+          you should run <code>bower uninstall silk domite --save</code>
+          from your CLI.</li>
+      <li>You cannot remove just the <code>DOMite</code> DOM wrapper
+          and retain the Silk package, as it depends on <code>domite</code>.</li>
+      <li>Your <code>Gruntfile.js</code> may contain references
+          to <code>Web</code> and/or <code>Silk</code> in <code>libraries</code>
+          field(s). Fix those fields to not contain non-existing libraries (optionally
+          add other needed ones, like <code>domite</code> or <code>Wrappers-JQuery</code>).</li>
+  </ul>
+  <p>If you are sure your app will only be run in modern browser / node.js
+      with Promise present, you can <code>bower uninstall amber-compat-es2015 --save</code>.</p>
+  <p>As the last step, make sure the dependency tree is in a correct state
+      by recreating it: first delete your <code>bower_components</code> folder,
+      then run <code>bower install</code> from your CLI.</p>
+  </body>
+
+</html>

+ 178 - 0
grunt-init-project/template.js

@@ -0,0 +1,178 @@
+/*
+ * grunt-init-amber
+ * https://amber-lang.net/
+ *
+ * Copyright (c) 2013 Manfred Kroehnert, contributors
+ * Licensed under the MIT license.
+ */
+
+'use strict';
+
+// Basic template description.
+exports.description = 'Create a web application based on Amber Smalltalk.';
+
+// Template-specific notes to be displayed before question prompts.
+exports.notes = ' _Project title_ should be a human-readable title.';
+
+// Template-specific notes to be displayed after question prompts.
+exports.after = 'You need to have these installed globally via npm:' +
+' _@ambers/cli_; _grunt-cli_; _bower_.' +
+' Now, install project dependencies with _bower install_,' +
+' tool dependencies with _npm install_ and recompile with _grunt_.' +
+' If you are running _amber init_, these three tasks are going to be performed for you now.' +
+' Afterwards, start the development server with _amber serve_.' +
+' Your application is then accessible via _http://localhost:4000/_';
+
+// Any existing file or directory matching this wildcard will cause a warning.
+exports.warnOn = '*';
+
+// The actual init template.
+exports.template = function (grunt, init, done) {
+    var remembered = {};
+
+    function rememberViaValidator(name) {
+        var oldValidator = init.prompts[name].validator || function (line) {
+                return true;
+            };
+
+        var newValidator;
+        switch (oldValidator.length) { //apply would not work, .length is used to call it differently
+            case 1:
+                newValidator = function (line) {
+                    remembered[name] = line;
+                    return oldValidator.call(this, line);
+                };
+                break;
+            case 2:
+                newValidator = function (line, next) {
+                    remembered[name] = line;
+                    return oldValidator.call(this, line, next);
+                };
+                break;
+            default:
+                throw new Error("Panic: " + oldValidator.length + "-argument validator for " + name + ".");
+        }
+
+        init.prompts[name].validator = newValidator;
+    }
+
+    function capitalize(string) {
+        return string[0].toUpperCase() + string.slice(1).toLowerCase();
+    }
+
+    init.prompts.name.message = 'Main class and package of Amber application.\nProject name is derived by lowercasing this.';
+    init.prompts.name.validator = function (line) {
+        return /^[A-Z][A-Za-z0-9]*$/.test(line)
+    };
+    init.prompts.name.warning = 'Must be a valid class name: only alphanumeric and starting with an uppercase letter!';
+    rememberViaValidator('name');
+    rememberViaValidator('title');
+
+    init.process({type: 'amber'}, [
+        // Prompt for these values.
+        init.prompt('title', 'Application or Library Title'),
+        init.prompt('name', function (value, data, done) {
+            var words = remembered.title.split(/\W/);
+            words = words.filter(function (x) {
+                return x && x !== "none";
+            }).map(capitalize);
+            value = words.length ? words.join('') : 'MysteriousApp';
+            done(null, value);
+        }),
+        init.prompt('description', 'The Application or The Library doing The Thing.'),
+        init.prompt('author_name'),
+        init.prompt('author_email'),
+        {
+            name: 'namespace',
+            message: 'Namespace of the new Amber package.',
+            altDefault: function (value, data, done) {
+                value = 'amber-' + remembered.name.toLowerCase();
+                done(null, value);
+            },
+            validator: /^[a-z][a-z0-9/\-]*$/,
+            warning: 'Only lowercase letters, numbers, and - are allowed in namespaces!'
+        },
+        init.prompt('version'),
+        init.prompt('repository'),
+        init.prompt('homepage'),
+        init.prompt('bugs'),
+        init.prompt('author_url'),
+        init.prompt('licenses', 'MIT')
+    ], function (err, props) {
+        // Files to copy (and process).
+        var files = init.filesToCopy(props);
+
+        // Add properly-named license files.
+        init.addLicenseFiles(files, props.licenses);
+
+        // Actually copy (and process) files.
+        init.copyAndProcess(files, props, {noProcess: 'libs/**'});
+
+        // Clean up non-npm props.
+        delete props.namespace;
+
+        props.name = props.name.toLowerCase();
+
+        // A few additional properties.
+        props.keywords = ['Amber', 'Smalltalk'];
+        props.devDependencies = {
+            "@ambers/sdk": "^0.10.6",
+            "grunt": "1.0.1",
+            "grunt-contrib-clean": "^1.1.0",
+            "grunt-contrib-requirejs": "^1.0.0",
+            "grunt-exec": "^2.0.0",
+            "requirejs": "^2.1.15"
+        };
+        props.node_version = '>=4.0.0';
+        props.scripts = {
+            "test": "grunt test"
+        };
+
+        // Generate package.json file, used by npm and grunt.
+        init.writePackageJSON('package.json', props);
+
+        // generate bower.json file
+        grunt.file.write('bower.json', JSON.stringify({
+            "name": props.name,
+            "description": props.description,
+            "ignore": [
+                "**/.*",
+                "node_modules",
+                "bower_components",
+                "/*.js",
+                "/*.html",
+                "test",
+                "tests"
+            ],
+            "authors": [
+                {
+                    "name": props.author_name,
+                    "email": props.author_email
+                }
+            ],
+            "homepage": props.homepage,
+            "main": props.main,
+            "keywords": props.keywords,
+            "license": props.licenses,
+            "private": false,
+            "dependencies": {
+                "amber": "^0.22.0",
+                "amber-compat-es2015": "^0.1.5",
+                "amber-contrib-jquery": "^0.4.1",
+                "amber-contrib-web": "^0.5.1",
+                "domite": "^0.7.1",
+                "silk": "^0.3.1"
+            },
+            "devDependencies": {
+                "amber-contrib-legacy": "^0.6.1",
+                "amber-ide-starter-dialog": "^0.1.0",
+                "helios": "^0.9.1"
+            }
+        }, null, 2));
+
+
+        // All done!
+        done();
+    });
+
+};