AWS CodeCommit is a Git repository service provided by Amazon Web Services. This service is like other AWS services in that it's scriptable via AWS command line, any of the language SDKs, or using AWS CloudFormation.
AWS CodeCommit is integrated with AWS IAM so roles related to Git repositories can be integrated with the rest of your AWS security. CodeCommit supports approval rule templates based on your IAM roles. This would require a separate configuration for GitHub for instance.
See example below to setup a git repository and assign a role to create branches in that repostory.
Go ahead and read Clojure(Script) Tools and return here to follow along.
Clojure has a large selection of tools you can use to manage dependencies and build deployment artifacts:
All of these projects, however, are Clojure specific and not designed to integrate into existing Java shops where Maven is the defacto build tool. There is talios/clojure-maven-plugin which is a very good Maven alternative but it's built using Maven mojos written in Java. I wanted a way to completely leverage maven while still allowing me to script build tasks in Clojure.
I want everything run via Maven so I get a classpath based on my dependencies but still script everything in Clojure.
Just Maven is an archetype. These give Clojure projects a base (archetype) from which to create new Clojure projects. It's not a plugin. It leverages an existing plugin, MojoHaus Exec. There are two initial scripts for compile and test phases that can be modified as needed. It's very easy to add new scripts for other tasks and everything continues to run via Maven.
When creating a new project, just run:
mvn archetype:generate ^
-DarchetypeGroupId=cloud.seltzer1717.clojure ^
-DarchetypeArtifactId=just-maven-clojure-archetype ^
-DarchetypeVersion=0.3-RELEASE
You'll then be prompted for your project's coordinates and root package:
Define value for property 'groupId': com.example
Define value for property 'artifactId': my-project
Define value for property 'version' 1.0-SNAPSHOT: :
Define value for property 'package' com.example: :
Confirm properties configuration:
groupId: com.example
artifactId: my-project
version: 1.0-SNAPSHOT
package: com.example
Y: : Y
This creates the following folder structure:
my-project
| pom.xml
| repl.bat
|
+---.clojure
| \---scripts
| build.clj
| test.clj
|
\---src
+---main
| +---java
| | \---com
| | \---example
| | App.java
| | core.clj
| |
| \---resources
| \---com
| \---example
+---site
| site.xml
|
\---test
\---java
\---com
\---example
AppTest.java
core_test.clj
A REPL can be launched by must running the repl.bat script.
repl.bat
C:\Users\jonseltzer\Documents\development\java\projects\my-project>repl
Clojure 1.10.1
user=>
Run mvn clean install to how Maven compiles both Java and Clojure including tests:
mvn clean install
...
There are two scripts which handle the compile and test phases. Here's the compile script:
;; Import Java classes
(import (java.nio.file SimpleFileVisitor FileVisitResult Files)
(java.io File))
;; Target folder
(def output-dir-file
"File representing target (or output) folder."
(-> (System/getProperties)
(get "clojure.compile.path")
(File.)))
;; Source directory
(def source-path
"Path representing source directory"
(-> (System/getProperties)
(get "maven.source.dir")
(File.)
(.toPath)))
;; FileVisitor compile proxy.
(def visitor
"Java SimpleFileVisitor - overrides visitFile:
takes path and attributes, compiles .clj files,
and returns FileVisitResult/CONTINUE"
(proxy [SimpleFileVisitor]
[]
(visitFile [path attributes]
(let [file-path (.toFile path)
string-path (.toString path)]
(if (.isFile file-path)
(if (.endsWith string-path ".clj")
(let [relative-path (.relativize source-path path)
relative-string (.toString relative-path)
dot-clj-index (.indexOf relative-string ".clj")
without-suffix (.substring relative-string 0 dot-clj-index)
;; standardizing windows systems
forward-slash (.replaceAll without-suffix "\\\\" "/")
underscores-to-dashes (.replaceAll forward-slash "_" "-")
source-namespace (.replaceAll underscores-to-dashes "/" ".")]
(load forward-slash)
(compile (symbol source-namespace))))))
FileVisitResult/CONTINUE)))
;; Create target/classes folders if missing.
(if (not (.exists output-dir-file))
(.mkdirs output-dir-file))
;; Walk source folder tree and compile Clojure source files.
(Files/walkFileTree source-path visitor)
ClojureScript is Clojure for JavaScript. ClojureScript is transpiled via Java. It uses Googles Closure. For ClojureScript we have a different archetype. So I need maven again to assist with Google and ClojureScript dependencies to create a classpath. However, after you have a classpath, maven is no longer useful. ClojureScript is designed with 54 separate transpilation options which control how build artifacts are created. Additionally, tools like npm, yarn, and others are needed to manage JavaScript dependencies, minification, and packaging. So this prototype only attempts to support the initial ClojureScript transpilation and REPL and does not try to manage any of these other things.
There are many targets for JavaScript: Web Browsers, NodeJS (Deno?), IOT hardware, and others. Web Browsers are an entirely different target than NodeJS. One optimizes JavaScript for deployment to a users browser while the other runs on the server. Additionally, applications deployed to a server will have a wide variety of deployment optimizations. In the case of this blog, I'm only interested in transpilation to a users browser with React.js and a transpilation to NodeJS for deployment to AWS Lambda. For now let's focus on NodeJS deployed to AWS Lambda.
mvn archetype:generate ^
-DarchetypeGroupId=cloud.seltzer1717.clojure ^
-DarchetypeArtifactId=just-maven-clojurescript-archetype ^
-DarchetypeVersion=0.21-RELEASE
This will create a ClojureScript project that can be used to create NodeJS programs to deploy where necessary. We'll look at this later when we talk about deploying NodeJS AWS Lambda functions in a future blog.