<commit_before>= boot-gae

A Boot library for Google App Engine development in Clojure.

[IMPORTANT]
====
This documentation is a little bit out of date, and, like the code, is
unpolished and partially incomplete.  In particular the reader will
probably need to have some idea of how boot works.
====

IMPORTANT: not yet pushed to clojars.  If you want to give it a try,
you must fork/clone it and run `$ boot pom jar install` to put it in
your local repo.

IMPORTANT: you do not need a GAE account to experiment!  The GAE SDK
contains everything you need to run webapps on the local devserver;
you only need a GAE account if you want to deploy to the production
servers.

= overview

=== toc

* <<start,getting started>>
* <<tasks>>
* <<configuration>>
* <<how,how it works>>
* <<repl>>
* <<config,config>>
* <<servlets,servlets>>
* <<config-map,configuration map>>
* <<pgming,gae programming with clojure>>

[[start]]
= getting started

Currently, `boot-gae` is not on clojars.  You'll have to fork/clone
the repo.  It contains `tasklib`, the task lib itself, and
`hello-gae`, a test/demo program that uses the tasklib.

[source,clojure]
.build.boot
----
...
:dependencies ... [migae/boot-gae "0.1.0-SNAPSHOT" :scope "test"] ...
...
(require '[migae.boot-gae :as gae] ...
----

[NOTE]
====
This documentation will use the namespace alias `gae`, as just shown,
to refer to boot-gae tasks.  For example, `gae/config` means `migae.boot-gae/config`.
====


Then you need to define a map named `gae` to configure things; see
<<config-map,below>> for details.

[source,clojure]
.build.boot
----
(def gae { ... details below ...}
----

[[tasks]]
= tasks

* <<configs,configuration tasks>>
 ** `<<config-appengine>>` generate gae `appengine-web.xml` config file
 ** `<<config-webapp>>`    generate gae `web.xml` config file
* `<<deploy>>`             install a new version of the application onto the server
* `<<dev>>`                build for dev (includes `reloader` task)
* `<<filters>>`            generate a "meta-filter" file with gen-class directives and aot-compile it to generate filters
* `<<install-sdk>>`        unpack and install the SDK zipfile
* `<<libs>>`               install dependency jars in <build-dir>/WEB-INF/lib
* `<<logging>>`		   generate and install gae logging config files (e.g. `logging.properties`, `log4j.properties`)
* `<<prod>>`		   build for production (without `reloader` task)
* `<<reloader>>`	   generate and aot-compile reloader filter used to support reload-on-refresh
* `<<run>>`		   run devappserver
* `<<servlets>>`	   generate a "meta-servlet" file with gen-class directives and aot-compile it to produce servlets
* `<<watch>>`		   watch input, write to output on change

[[configs]]
=== configuration

Both the `WEB-INF/appengine-web.xml` and `WEB-INF/web.xml`
configuration files required by the GAE servlet container are
automatically generated from your configuration map.  The dev server
will automatically reload `appengine-web.xml` if it changes, but
unfortunately the same cannot be said for `web.xml`. If you change it
- that is, if you change your configuration map and re-run
`gae/config` -- you need to restart the dev server.  For example:

[source,shell]
----
$ boot gae/config target -C -d "build"
$ boot gae/run
----

[NOTE]
====
For the moment you need to run gae/run as a separate step as shown here.  If you
tack it on the end of the first boot command shown here, boot seems to
launch the dev server before the gae/config task has completed.
====

==== aot

The builtin `aot` command does not allow specification of output dir so we hacked it up

[[config-appengine]]
==== appengine

Generates `WEB-INF/appengine-web.xml` from `appengine.edn`

==== appstats

Enables Google's built-in Appstats service.  Configure in `appstats.edn`

==== clj

Move clojure source files to `WEB-INF/classes`

[[deploy]]
=== deploy

You will obviously need a GAE account to deploy.

To deploy run `$ boot gae/deploy`.

[[dev]]
=== dev

The build pipeline:

[source,clojure]
----
  (comp (install-sdk)
        (libs)
        (logging)
        (clj)
        (appstats)
        (filters :keep keep)
        (servlets :keep keep)
        (reloader :keep keep)
        (webxml)
        (appengine)
        ))
----

Some of the tasks can be run in any order (e.g. filters and servlets) but `webxml` must be run after `servlets`, `filters`, `appstats` and `reloader`, since it uses the `web.xml.edn` file they elaborate.  The `reloader` ``filters`, and `appstats` tasks are optional.

[[filters]]
=== filters

[[install-sdk]]
=== install-sdk

[[libs]]
=== libs

Copy all dependency jars to `WEB-INF/lib`, required by Appengine.

[[logging]]
=== logging

[[reloader]]
=== reloader

Install a servlet filter to support reload-on-refresh in conjunction
with the `watch` task.  For use during development, in order to get
repl-like responsiveness.  Run `gae/reloader -k` to see the intermediate files.

[[run]]
=== run

[[servlets]]
=== servlets

Servlets can be implemented in Clojure in a variety of ways; boot-gae
supports the technique described here out of the box, via the
`gae/servlets` task.  That task reads the `gae` configuration map from
`build.boot`, processes a stencil template file to generate a Clojure
source file, and then aot compiles that source file.

WARNING: the following config example is obsolete - boot-gae now uses<commit_msg>more README<commit_after>= boot-gae

A Boot library for Google App Engine development in Clojure.

[IMPORTANT]
====
This documentation is a little bit out of date, and, like the code, is
unpolished and partially incomplete.  In particular the reader will
probably need to have some idea of how boot works.
====

IMPORTANT: not yet pushed to clojars.  If you want to give it a try,
you must fork/clone it and run `$ boot pom jar install` to put it in
your local repo.

IMPORTANT: you do not need a GAE account to experiment!  The GAE SDK
contains everything you need to run webapps on the local devserver;
you only need a GAE account if you want to deploy to the production
servers.

= overview

=== toc

* <<start,getting started>>
* <<tasks>>
* <<configuration>>
* <<how,how it works>>
* <<repl>>
* <<config,config>>
* <<servlets,servlets>>
* <<config-map,configuration map>>
* <<pgming,gae programming with clojure>>

[[start]]
= getting started

Currently, `boot-gae` is not on clojars.  You'll have to fork/clone
the repo.  It contains `tasklib`, the task lib itself, and
`hello-gae`, a test/demo program that uses the tasklib.

[source,clojure]
.build.boot
----
...
:dependencies ... [migae/boot-gae "0.1.0-SNAPSHOT" :scope "test"] ...
...
(require '[migae.boot-gae :as gae] ...
----

[NOTE]
====
This documentation will use the namespace alias `gae`, as just shown,
to refer to boot-gae tasks.  For example, `gae/config` means `migae.boot-gae/config`.
====


Then you need to define a map named `gae` to configure things; see
<<config-map,below>> for details.

[source,clojure]
.build.boot
----
(def gae { ... details below ...}
----

[[tasks]]
= tasks

* <<configs,configuration tasks>>
 ** `<<config-appengine>>` generate gae `appengine-web.xml` config file
 ** `<<config-webapp>>`    generate gae `web.xml` config file
* `<<deploy>>`             install a new version of the application onto the server
* `<<dev>>`                build for dev (includes `reloader` task)
* `<<filters>>`            generate a "meta-filter" file with gen-class directives and aot-compile it to generate filters
* `<<install-sdk>>`        unpack and install the SDK zipfile
* `<<libs>>`               install dependency jars in <build-dir>/WEB-INF/lib
* `<<logging>>`		   generate and install gae logging config files (e.g. `logging.properties`, `log4j.properties`)
* `<<prod>>`		   build for production (without `reloader` task)
* `<<reloader>>`	   generate and aot-compile reloader filter used to support reload-on-refresh
* `<<run>>`		   run devappserver
* `<<servlets>>`	   generate a "meta-servlet" file with gen-class directives and aot-compile it to produce servlets
* `<<watch>>`		   watch input, write to output on change

[[configs]]
=== configuration

Both the `WEB-INF/appengine-web.xml` and `WEB-INF/web.xml`
configuration files required by the GAE servlet container are
automatically generated from your configuration map.  The dev server
will automatically reload `appengine-web.xml` if it changes, but
unfortunately the same cannot be said for `web.xml`. If you change it
- that is, if you change your configuration map and re-run
`gae/config` -- you need to restart the dev server.  For example:

[source,shell]
----
$ boot gae/config target -C -d "build"
$ boot gae/run
----

[NOTE]
====
For the moment you need to run gae/run as a separate step as shown here.  If you
tack it on the end of the first boot command shown here, boot seems to
launch the dev server before the gae/config task has completed.
====

==== aot

The builtin `aot` command does not allow specification of output dir so we hacked it up

[[config-appengine]]
==== appengine

Generates `WEB-INF/appengine-web.xml` from `appengine.edn`

==== appstats

Enables Google's built-in Appstats service.  Configure in `appstats.edn`

==== clj

Move clojure source files to `WEB-INF/classes`

[[deploy]]
=== deploy

You will obviously need a GAE account to deploy.

To deploy run `$ boot gae/deploy`.

[[dev]]
=== dev

The build pipeline:

[source,clojure]
----
  (comp (install-sdk)
        (libs)
        (logging)
        (clj)
        (appstats)
        (filters :keep keep)
        (servlets :keep keep)
        (reloader :keep keep)
        (webxml)
        (appengine)
        ))
----

Some of the tasks can be run in any order (e.g. filters and servlets) but `webxml` must be run after `servlets`, `filters`, `appstats` and `reloader`, since it uses the `web.xml.edn` file they elaborate.  The `reloader` ``filters`, and `appstats` tasks are optional.

[[filters]]
=== filters

[[install-sdk]]
=== install-sdk

[[libs]]
=== libs

Copy all dependency jars to `WEB-INF/lib`, required by Appengine.

[[logging]]
=== logging

[[reloader]]
=== reloader

Install a servlet filter to support reload-on-refresh in conjunction
with the `watch` task.  For use during development, in order to get
repl-like responsiveness.  Run `gae/reloader -k` to see the intermediate files.

[[run]]
=== run

==== security

Add security-constraint stanzas to `web.xml`.  Configuration data goes in `security.edn`.

WARNING: not yet implemented


[[servlets]]
=== servlets

Servlets can be implemented in Clojure in a variety of ways; boot-gae
supports the technique described here out of the box, via the
`gae/servlets` task.  That task reads the `gae` configuration map from
`build.boot`, processes a stencil template file to generate a Clojure
source file, and then aot compiles that source file.

WARNING: the following config example is obsolete - boot-gae now uses
{'fraction_non_alphanumeric': 0.1228794131132508, 'fraction_numerical': 0.0007336084364970197, 'mean_word_length': 3.6329651656754463, 'pattern_counts': {'":': 0, '<': 101, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 21}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3471557', 'n_tokens_mistral': 3427, 'n_tokens_neox': 3307, 'n_words': 1389}