diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..3420e36
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,81 @@
+name: CI
+
+on:
+ push:
+ branches: [ main ]
+
+jobs:
+ build_test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v2
+
+ - name: Use OCaml 4.13.x
+ uses: ocaml/setup-ocaml@v2
+ with:
+ ocaml-compiler: 4.13.x
+
+ - name: Install Dependencies
+ run: |
+ opam install . --deps-only --with-test
+ eval $(opam env)
+
+ - name: Build Emulator
+ run: make build
+
+ - name: Run Unit Tests
+ run: make test
+
+ build_docs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v2
+
+ - name: Use OCaml 4.13.x
+ uses: ocaml/setup-ocaml@v2
+ with:
+ ocaml-compiler: 4.13.x
+
+ - name: Install Dependencies
+ run: |
+ opam install . --deps-only --with-doc
+ eval $(opam env)
+
+ - name: Build Documentation
+ run: |
+ make docs
+
+ - name: Copy documentation to gh-pages branch
+ uses: actions/upload-artifact@v3
+ with:
+ name: docs
+ path: docs
+ retention-days: 1
+
+ publish_docs:
+ runs-on: ubuntu-latest
+ needs: build_docs
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ ref: gh-pages
+
+ - name: Download documentation files
+ uses: actions/download-artifact@v2
+ with:
+ name: docs
+ path: docs
+
+ - name: Commit
+ uses: EndBug/add-and-commit@v9
+ with:
+ author_name: _AUTHOR_NAME_
+ author_email: _AUTHOR_EMAIL_
+ message: "Latest docs - ${{ github.event.repository.updated_at}}"
+ branch: gh-pages
+ add: '[./*]'
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..99f3798
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+*~
+*.annot
+*.cmo
+*.cma
+*.cmi
+*.a
+*.o
+*.cmx
+*.cmxs
+*.cmxa
+_build
diff --git a/.ocamlformat b/.ocamlformat
new file mode 100644
index 0000000..b73a05f
--- /dev/null
+++ b/.ocamlformat
@@ -0,0 +1 @@
+version=0.25.1
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8143177
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 _AUTHOR_NAME_
+
+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.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..34b5b2d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,77 @@
+.PHONY: default build install uninstall test clean fmt
+.IGNORE: fmt
+
+default: build
+
+fmt:
+ opam exec -- dune build @fmt
+ opam exec -- dune promote
+
+build: fmt
+ opam exec -- dune build
+
+install:
+ opam exec -- dune install
+
+uninstall:
+ opam exec -- dune uninstall
+
+clean:
+ opam exec -- dune clean
+ git clean -dfXq
+
+test: fmt
+ opam exec -- dune runtest
+
+testf: fmt
+ opam exec -- dune runtest -f
+
+run: build
+ opam exec -- dune exec -- _PROJECT_NAME_
+
+raw_run: build
+ clear
+ _build/default/bin/main.exe
+
+debug: build
+ opam exec -- ocamldebug _build/default/_PROJECT_NAME_/main.bc
+
+DOCS_PATH=docs/
+DOCS_NAME=_PROJECT_NAME_
+DOCS_DESCR=An Ocaml Window Manager
+DOCS_INDEX_TITLE=$(DOCS_NAME) - $(DOCS_DESCR)
+define DOCS_EMBED
+\
+\
+
+endef
+
+cleandocs:
+ if [ ! -d $(DOCS_PATH) ]; then \
+ mkdir $(DOCS_PATH); \
+ fi
+ rm -rf $(DOCS_PATH)module $(DOCS_PATH)docs $(DOCS_PATH)odoc.support $(DOCS_PATH)index.html
+
+docs: cleandocs build
+ opam exec -- dune build @doc
+ mv -f _build/default/_doc/_html/* $(DOCS_PATH)
+ rm -f $(DOCS_PATH)index.html
+ mv $(DOCS_PATH)_PROJECT_NAME_/_PROJECT_NAME_.html $(DOCS_PATH)index.html
+ mv $(DOCS_PATH)_PROJECT_NAME_ $(DOCS_PATH)module
+
+ @echo "Preparing Index\n--------------"
+ # Header
+ sed -i 's/
.*<\/title>/$(DOCS_INDEX_TITLE)<\/title>/g' $(DOCS_PATH)index.html
+ sed -i 's@@\n@g' $(DOCS_PATH)index.html
+ sed -i 's@@$(DOCS_EMBED)\n@g' $(DOCS_PATH)index.html
+ sed -i 's/..\/odoc.support/odoc.support/g' $(DOCS_PATH)index.html
+ # Body
+ sed -i 's@@@g' $(DOCS_PATH)index.html
+
+push: cleandocs build
+ @read -p "Commit message: " input; \
+ if [ -z "$input" ]; then \
+ echo "Error: Please provide a valid commit message."; \
+ exit 1; \
+ fi; \
+ git add . && git commit -m "$$input" && git push origin main
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..227b704
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Friendly OCaml Template
+
+Just run `setup.sh` to set up a ready-for-development OCaml environment
diff --git a/bin/dune b/bin/dune
new file mode 100644
index 0000000..75a89fa
--- /dev/null
+++ b/bin/dune
@@ -0,0 +1,4 @@
+(executable
+ (public_name _PROJECT_NAME_)
+ (name main)
+ (libraries _PROJECT_NAME_))
diff --git a/bin/main.ml b/bin/main.ml
new file mode 100644
index 0000000..7bf6048
--- /dev/null
+++ b/bin/main.ml
@@ -0,0 +1 @@
+let () = print_endline "Hello, World!"
diff --git a/dune-project b/dune-project
new file mode 100644
index 0000000..557291e
--- /dev/null
+++ b/dune-project
@@ -0,0 +1,23 @@
+(lang dune 3.9)
+
+(name _PROJECT_NAME_)
+
+(generate_opam_files true)
+
+(source
+ (github _AUTHOR_USERNAME_/_PROJECT_NAME_))
+
+(authors "_AUTHOR_NAME_")
+
+(maintainers "_AUTHOR_NAME_")
+
+(license LICENSE)
+
+(documentation https://github.com/_AUTHOR_USERNAME_/_PROJECT_NAME_)
+
+(package
+ (name _PROJECT_NAME_)
+ (synopsis "An OCaml Window Mangaer")
+ (description "A window manager built on top of the Graphics library")
+ (depends ocaml dune graphics))
+
diff --git a/gbcamel.odocl b/gbcamel.odocl
new file mode 100644
index 0000000..8c7081a
--- /dev/null
+++ b/gbcamel.odocl
@@ -0,0 +1 @@
+dir: ./docs
diff --git a/lib/dune b/lib/dune
new file mode 100644
index 0000000..923ddda
--- /dev/null
+++ b/lib/dune
@@ -0,0 +1,2 @@
+(library
+ (name _PROJECT_NAME_))
diff --git a/ocaml_template/.github/workflows/ci.yml b/ocaml_template/.github/workflows/ci.yml
new file mode 100644
index 0000000..3420e36
--- /dev/null
+++ b/ocaml_template/.github/workflows/ci.yml
@@ -0,0 +1,81 @@
+name: CI
+
+on:
+ push:
+ branches: [ main ]
+
+jobs:
+ build_test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v2
+
+ - name: Use OCaml 4.13.x
+ uses: ocaml/setup-ocaml@v2
+ with:
+ ocaml-compiler: 4.13.x
+
+ - name: Install Dependencies
+ run: |
+ opam install . --deps-only --with-test
+ eval $(opam env)
+
+ - name: Build Emulator
+ run: make build
+
+ - name: Run Unit Tests
+ run: make test
+
+ build_docs:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v2
+
+ - name: Use OCaml 4.13.x
+ uses: ocaml/setup-ocaml@v2
+ with:
+ ocaml-compiler: 4.13.x
+
+ - name: Install Dependencies
+ run: |
+ opam install . --deps-only --with-doc
+ eval $(opam env)
+
+ - name: Build Documentation
+ run: |
+ make docs
+
+ - name: Copy documentation to gh-pages branch
+ uses: actions/upload-artifact@v3
+ with:
+ name: docs
+ path: docs
+ retention-days: 1
+
+ publish_docs:
+ runs-on: ubuntu-latest
+ needs: build_docs
+
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ ref: gh-pages
+
+ - name: Download documentation files
+ uses: actions/download-artifact@v2
+ with:
+ name: docs
+ path: docs
+
+ - name: Commit
+ uses: EndBug/add-and-commit@v9
+ with:
+ author_name: _AUTHOR_NAME_
+ author_email: _AUTHOR_EMAIL_
+ message: "Latest docs - ${{ github.event.repository.updated_at}}"
+ branch: gh-pages
+ add: '[./*]'
diff --git a/ocaml_template/.gitignore b/ocaml_template/.gitignore
new file mode 100644
index 0000000..99f3798
--- /dev/null
+++ b/ocaml_template/.gitignore
@@ -0,0 +1,11 @@
+*~
+*.annot
+*.cmo
+*.cma
+*.cmi
+*.a
+*.o
+*.cmx
+*.cmxs
+*.cmxa
+_build
diff --git a/ocaml_template/.ocamlformat b/ocaml_template/.ocamlformat
new file mode 100644
index 0000000..b73a05f
--- /dev/null
+++ b/ocaml_template/.ocamlformat
@@ -0,0 +1 @@
+version=0.25.1
diff --git a/ocaml_template/LICENSE b/ocaml_template/LICENSE
new file mode 100644
index 0000000..8143177
--- /dev/null
+++ b/ocaml_template/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 _AUTHOR_NAME_
+
+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.
diff --git a/ocaml_template/Makefile b/ocaml_template/Makefile
new file mode 100644
index 0000000..34b5b2d
--- /dev/null
+++ b/ocaml_template/Makefile
@@ -0,0 +1,77 @@
+.PHONY: default build install uninstall test clean fmt
+.IGNORE: fmt
+
+default: build
+
+fmt:
+ opam exec -- dune build @fmt
+ opam exec -- dune promote
+
+build: fmt
+ opam exec -- dune build
+
+install:
+ opam exec -- dune install
+
+uninstall:
+ opam exec -- dune uninstall
+
+clean:
+ opam exec -- dune clean
+ git clean -dfXq
+
+test: fmt
+ opam exec -- dune runtest
+
+testf: fmt
+ opam exec -- dune runtest -f
+
+run: build
+ opam exec -- dune exec -- _PROJECT_NAME_
+
+raw_run: build
+ clear
+ _build/default/bin/main.exe
+
+debug: build
+ opam exec -- ocamldebug _build/default/_PROJECT_NAME_/main.bc
+
+DOCS_PATH=docs/
+DOCS_NAME=_PROJECT_NAME_
+DOCS_DESCR=An Ocaml Window Manager
+DOCS_INDEX_TITLE=$(DOCS_NAME) - $(DOCS_DESCR)
+define DOCS_EMBED
+\
+\
+
+endef
+
+cleandocs:
+ if [ ! -d $(DOCS_PATH) ]; then \
+ mkdir $(DOCS_PATH); \
+ fi
+ rm -rf $(DOCS_PATH)module $(DOCS_PATH)docs $(DOCS_PATH)odoc.support $(DOCS_PATH)index.html
+
+docs: cleandocs build
+ opam exec -- dune build @doc
+ mv -f _build/default/_doc/_html/* $(DOCS_PATH)
+ rm -f $(DOCS_PATH)index.html
+ mv $(DOCS_PATH)_PROJECT_NAME_/_PROJECT_NAME_.html $(DOCS_PATH)index.html
+ mv $(DOCS_PATH)_PROJECT_NAME_ $(DOCS_PATH)module
+
+ @echo "Preparing Index\n--------------"
+ # Header
+ sed -i 's/.*<\/title>/$(DOCS_INDEX_TITLE)<\/title>/g' $(DOCS_PATH)index.html
+ sed -i 's@@\n@g' $(DOCS_PATH)index.html
+ sed -i 's@@$(DOCS_EMBED)\n@g' $(DOCS_PATH)index.html
+ sed -i 's/..\/odoc.support/odoc.support/g' $(DOCS_PATH)index.html
+ # Body
+ sed -i 's@@@g' $(DOCS_PATH)index.html
+
+push: cleandocs build
+ @read -p "Commit message: " input; \
+ if [ -z "$input" ]; then \
+ echo "Error: Please provide a valid commit message."; \
+ exit 1; \
+ fi; \
+ git add . && git commit -m "$$input" && git push origin main
diff --git a/ocaml_template/bin/dune b/ocaml_template/bin/dune
new file mode 100644
index 0000000..75a89fa
--- /dev/null
+++ b/ocaml_template/bin/dune
@@ -0,0 +1,4 @@
+(executable
+ (public_name _PROJECT_NAME_)
+ (name main)
+ (libraries _PROJECT_NAME_))
diff --git a/ocaml_template/bin/main.ml b/ocaml_template/bin/main.ml
new file mode 100644
index 0000000..7bf6048
--- /dev/null
+++ b/ocaml_template/bin/main.ml
@@ -0,0 +1 @@
+let () = print_endline "Hello, World!"
diff --git a/ocaml_template/dune-project b/ocaml_template/dune-project
new file mode 100644
index 0000000..557291e
--- /dev/null
+++ b/ocaml_template/dune-project
@@ -0,0 +1,23 @@
+(lang dune 3.9)
+
+(name _PROJECT_NAME_)
+
+(generate_opam_files true)
+
+(source
+ (github _AUTHOR_USERNAME_/_PROJECT_NAME_))
+
+(authors "_AUTHOR_NAME_")
+
+(maintainers "_AUTHOR_NAME_")
+
+(license LICENSE)
+
+(documentation https://github.com/_AUTHOR_USERNAME_/_PROJECT_NAME_)
+
+(package
+ (name _PROJECT_NAME_)
+ (synopsis "An OCaml Window Mangaer")
+ (description "A window manager built on top of the Graphics library")
+ (depends ocaml dune graphics))
+
diff --git a/ocaml_template/gbcamel.odocl b/ocaml_template/gbcamel.odocl
new file mode 100644
index 0000000..8c7081a
--- /dev/null
+++ b/ocaml_template/gbcamel.odocl
@@ -0,0 +1 @@
+dir: ./docs
diff --git a/ocaml_template/lib/dune b/ocaml_template/lib/dune
new file mode 100644
index 0000000..923ddda
--- /dev/null
+++ b/ocaml_template/lib/dune
@@ -0,0 +1,2 @@
+(library
+ (name _PROJECT_NAME_))
diff --git a/ocaml_template/setup.sh b/ocaml_template/setup.sh
new file mode 100755
index 0000000..ffdb6d7
--- /dev/null
+++ b/ocaml_template/setup.sh
@@ -0,0 +1,7 @@
+read -p "Project Name: " PROJECT_NAME
+read -p "Author Name: " AUTHOR_NAME
+read -p "Author Github Username: " AUTHOR_USERNAME
+read -p "Author email (for CI): " AUTHOR_EMAIL
+
+find . -type f -exec sed -i "s/_PROJECT_NAME_/$PROJECT_NAME/g; s/_AUTHOR_NAME_/$AUTHOR_NAME/g; s/_AUTHOR_USERNAME_/$AUTHOR_USERNAME/g; s/_AUTHOR_EMAIL_/$AUTHOR_EMAIL/g" {} +
+touch "test/$PROJECT_NAME.ml"
diff --git a/ocaml_template/test/dune b/ocaml_template/test/dune
new file mode 100644
index 0000000..b81d14f
--- /dev/null
+++ b/ocaml_template/test/dune
@@ -0,0 +1,2 @@
+(test
+ (name _PROJECT_NAME_))
diff --git a/ocaml_template/test/owm.ml b/ocaml_template/test/owm.ml
new file mode 100644
index 0000000..e69de29
diff --git a/setup.sh b/setup.sh
new file mode 100755
index 0000000..e6b93c9
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,9 @@
+read -p "Project Name: " PROJECT_NAME
+read -p "Author Name: " AUTHOR_NAME
+read -p "Author Github Username: " AUTHOR_USERNAME
+read -p "Author email (for CI): " AUTHOR_EMAIL
+
+find . -type f -exec sed -i "s/_PROJECT_NAME_/$PROJECT_NAME/g; s/_AUTHOR_NAME_/$AUTHOR_NAME/g; s/_AUTHOR_USERNAME_/$AUTHOR_USERNAME/g; s/_AUTHOR_EMAIL_/$AUTHOR_EMAIL/g" {} +
+touch "test/$PROJECT_NAME.ml"
+
+rm setup.sh
diff --git a/test/dune b/test/dune
new file mode 100644
index 0000000..b81d14f
--- /dev/null
+++ b/test/dune
@@ -0,0 +1,2 @@
+(test
+ (name _PROJECT_NAME_))
diff --git a/test/owm.ml b/test/owm.ml
new file mode 100644
index 0000000..e69de29