diff --git a/simple/Makefile b/simple/Makefile index 8c47d39..d8ac904 100644 --- a/simple/Makefile +++ b/simple/Makefile @@ -1,240 +1,14 @@ +#---------------------------------------------------------------------- +# GLOBAL MAKEFILE +#---------------------------------------------------------------------- -##---------------------------------------------------------------------- -## DISCLAIMER -## -## This file contains the rules to make an Eliom project. The project is -## configured through the variables in the file Makefile.options. -##---------------------------------------------------------------------- +# Local settings (optional). See Makefile.local.example for an example. +# WARNING: do not commit to a repository! +-include Makefile.local +# Eliom settings. Contains all variables. include Makefile.options -##---------------------------------------------------------------------- -## Internals - -## Required binaries -ELIOMC := eliomc -ppx -ELIOMOPT := eliomopt -ppx -JS_OF_ELIOM := js_of_eliom -ppx -ELIOMDEP := eliomdep -OCSIGENSERVER := ocsigenserver -OCSIGENSERVER.OPT := ocsigenserver.opt - -## Where to put intermediate object files. -## - ELIOM_{SERVER,CLIENT}_DIR must be distinct -## - ELIOM_CLIENT_DIR must not be the local dir. -## - ELIOM_SERVER_DIR could be ".", but you need to -## remove it from the "clean" rules... -export ELIOM_SERVER_DIR := _server -export ELIOM_CLIENT_DIR := _client -export ELIOM_TYPE_DIR := _server -DEPSDIR := _deps - -ifeq ($(DEBUG),yes) - GENERATE_DEBUG ?= -g - RUN_DEBUG ?= "-v" - DEBUG_JS ?= -jsopt -pretty -jsopt -noinline -jsopt -debuginfo -endif - -##---------------------------------------------------------------------- -## General - -.PHONY: all byte opt -all: byte opt -byte opt:: $(TEST_PREFIX)$(ELIOMSTATICDIR)/${PROJECT_NAME}.js -byte opt:: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf -byte opt:: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME)-test.conf -byte:: $(TEST_PREFIX)$(LIBDIR)/${PROJECT_NAME}.cma -opt:: $(TEST_PREFIX)$(LIBDIR)/${PROJECT_NAME}.cmxs - -DIST_DIRS = $(ETCDIR) $(DATADIR) $(LIBDIR) $(LOGDIR) $(STATICDIR) $(ELIOMSTATICDIR) $(shell dirname $(CMDPIPE)) - -##---------------------------------------------------------------------- -## Testing - -DIST_FILES = $(ELIOMSTATICDIR)/$(PROJECT_NAME).js $(LIBDIR)/$(PROJECT_NAME).cma - -.PHONY: test.byte test.opt -test.byte: $(addprefix $(TEST_PREFIX),$(ETCDIR)/$(PROJECT_NAME)-test.conf $(DIST_DIRS) $(DIST_FILES)) - $(OCSIGENSERVER) $(RUN_DEBUG) -c $< -test.opt: $(addprefix $(TEST_PREFIX),$(ETCDIR)/$(PROJECT_NAME)-test.conf $(DIST_DIRS) $(patsubst %.cma,%.cmxs, $(DIST_FILES))) - $(OCSIGENSERVER.OPT) $(RUN_DEBUG) -c $< - -$(addprefix $(TEST_PREFIX), $(DIST_DIRS)): - mkdir -p $@ - -##---------------------------------------------------------------------- -## Installing & Running - -.PHONY: install install.byte install.byte install.opt install.static install.etc install.lib install.lib.byte install.lib.opt run.byte run.opt -install: install.byte install.opt -install.byte: install.lib.byte install.etc install.static | $(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(shell dirname $(CMDPIPE))) -install.opt: install.lib.opt install.etc install.static | $(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(shell dirname $(CMDPIPE))) -install.lib: install.lib.byte install.lib.opt -install.lib.byte: $(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cma | $(PREFIX)$(LIBDIR) - install $< $(PREFIX)$(LIBDIR) -install.lib.opt: $(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cmxs | $(PREFIX)$(LIBDIR) - install $< $(PREFIX)$(LIBDIR) -install.static: $(TEST_PREFIX)$(ELIOMSTATICDIR)/$(PROJECT_NAME).js | $(PREFIX)$(STATICDIR) $(PREFIX)$(ELIOMSTATICDIR) - cp -r $(LOCAL_STATIC)/* $(PREFIX)$(STATICDIR) - [ -z $(WWWUSER) ] || chown -R $(WWWUSER) $(PREFIX)$(STATICDIR) - install $(addprefix -o ,$(WWWUSER)) $< $(PREFIX)$(ELIOMSTATICDIR) -install.etc: $(TEST_PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf | $(PREFIX)$(ETCDIR) - install $< $(PREFIX)$(ETCDIR)/$(PROJECT_NAME).conf - -.PHONY: -print-install-files: - @echo $(PREFIX)$(LIBDIR) - @echo $(PREFIX)$(STATICDIR) - @echo $(PREFIX)$(ELIOMSTATICDIR) - @echo $(PREFIX)$(ETCDIR) - -$(addprefix $(PREFIX),$(ETCDIR) $(LIBDIR)): - install -d $@ -$(addprefix $(PREFIX),$(DATADIR) $(LOGDIR) $(STATICDIR) $(ELIOMSTATICDIR) $(shell dirname $(CMDPIPE))): - install $(addprefix -o ,$(WWWUSER)) -d $@ - -run.byte: - $(OCSIGENSERVER) $(RUN_DEBUG) -c ${PREFIX}${ETCDIR}/${PROJECT_NAME}.conf -run.opt: - $(OCSIGENSERVER.OPT) $(RUN_DEBUG) -c ${PREFIX}${ETCDIR}/${PROJECT_NAME}.conf - -##---------------------------------------------------------------------- -## Aux - -# Use `eliomdep -sort' only in OCaml>4 -ifeq ($(shell ocamlc -version|cut -c1),4) -eliomdep=$(shell $(ELIOMDEP) $(1) -ppx -sort $(2) $(filter %.eliom %.ml,$(3)))) -else -eliomdep=$(3) -endif -objs=$(patsubst %.ml,$(1)/%.$(2),$(patsubst %.eliom,$(1)/%.$(2),$(filter %.eliom %.ml,$(3)))) -depsort=$(call objs,$(1),$(2),$(call eliomdep,$(3),$(4),$(5))) - -##---------------------------------------------------------------------- -## Config files - -FINDLIB_PACKAGES=$(patsubst %,\,$(SERVER_PACKAGES)) -EDIT_WARNING=DON\'T EDIT THIS FILE! It is generated from $(PROJECT_NAME).conf.in, edit that one, or the variables in Makefile.options -SED_ARGS := -e "/^ *%%%/d" -SED_ARGS += -e "s|%%PROJECT_NAME%%|$(PROJECT_NAME)|g" -SED_ARGS += -e "s|%%DATABASE_NAME%%|$(DATABASE_NAME)|g" -SED_ARGS += -e "s|%%DATABASE_USER%%|$(DATABASE_USER)|g" -SED_ARGS += -e "s|%%CMDPIPE%%|%%PREFIX%%$(CMDPIPE)|g" -SED_ARGS += -e "s|%%LOGDIR%%|%%PREFIX%%$(LOGDIR)|g" -SED_ARGS += -e "s|%%DATADIR%%|%%PREFIX%%$(DATADIR)|g" -SED_ARGS += -e "s|%%PERSISTENT_DATA_BACKEND%%|$(PERSISTENT_DATA_BACKEND)|g" -SED_ARGS += -e "s|%%LIBDIR%%|%%PREFIX%%$(LIBDIR)|g" -SED_ARGS += -e "s|%%WARNING%%|$(EDIT_WARNING)|g" -SED_ARGS += -e "s|%%PACKAGES%%|$(FINDLIB_PACKAGES)|g" -SED_ARGS += -e "s|%%ELIOMSTATICDIR%%|%%PREFIX%%$(ELIOMSTATICDIR)|g" -ifeq ($(DEBUG),yes) - SED_ARGS += -e "s|%%DEBUGMODE%%|\|g" -else - SED_ARGS += -e "s|%%DEBUGMODE%%||g" -endif - -LOCAL_SED_ARGS := -e "s|%%PORT%%|$(TEST_PORT)|g" -LOCAL_SED_ARGS += -e "s|%%STATICDIR%%|$(LOCAL_STATIC)|g" -LOCAL_SED_ARGS += -e "s|%%USERGROUP%%||g" -GLOBAL_SED_ARGS := -e "s|%%PORT%%|$(PORT)|g" -GLOBAL_SED_ARGS += -e "s|%%STATICDIR%%|%%PREFIX%%$(STATICDIR)|g" -ifeq ($(WWWUSER)$(WWWGROUP),) - GLOBAL_SED_ARGS += -e "s|%%USERGROUP%%||g" -else - GLOBAL_SED_ARGS += -e "s|%%USERGROUP%%|$(WWWUSER)$(WWWGROUP)|g" -endif - -$(TEST_PREFIX)${ETCDIR}/${PROJECT_NAME}.conf: ${PROJECT_NAME}.conf.in Makefile.options | $(TEST_PREFIX)$(ETCDIR) - sed $(SED_ARGS) $(GLOBAL_SED_ARGS) $< | sed -e "s|%%PREFIX%%|$(PREFIX)|g" > $@ -$(TEST_PREFIX)${ETCDIR}/${PROJECT_NAME}-test.conf: ${PROJECT_NAME}.conf.in Makefile.options | $(TEST_PREFIX)$(ETCDIR) - sed $(SED_ARGS) $(LOCAL_SED_ARGS) $< | sed -e "s|%%PREFIX%%|$(TEST_PREFIX)|g" > $@ - -##---------------------------------------------------------------------- -## Server side compilation - -SERVER_INC := ${addprefix -package ,${SERVER_PACKAGES}} - -${ELIOM_TYPE_DIR}/%.type_mli: %.eliom - ${ELIOMC} -infer ${SERVER_INC} $< - -$(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cma: $(call objs,$(ELIOM_SERVER_DIR),cmo,$(SERVER_FILES)) | $(TEST_PREFIX)$(LIBDIR) - ${ELIOMC} -a -o $@ $(GENERATE_DEBUG) \ - $(call depsort,$(ELIOM_SERVER_DIR),cmo,-server,$(SERVER_INC),$(SERVER_FILES)) - -$(TEST_PREFIX)$(LIBDIR)/$(PROJECT_NAME).cmxa: $(call objs,$(ELIOM_SERVER_DIR),cmx,$(SERVER_FILES)) | $(TEST_PREFIX)$(LIBDIR) - ${ELIOMOPT} -a -o $@ $(GENERATE_DEBUG) \ - $(call depsort,$(ELIOM_SERVER_DIR),cmx,-server,$(SERVER_INC),$(SERVER_FILES)) - -%.cmxs: %.cmxa - $(ELIOMOPT) -shared -linkall -o $@ $(GENERATE_DEBUG) $< - -${ELIOM_SERVER_DIR}/%.cmi: %.mli - ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< - -${ELIOM_SERVER_DIR}/%.cmi: %.eliomi - ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< - -${ELIOM_SERVER_DIR}/%.cmo: %.ml - ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< -${ELIOM_SERVER_DIR}/%.cmo: %.eliom - ${ELIOMC} -c ${SERVER_INC} $(GENERATE_DEBUG) $< - -${ELIOM_SERVER_DIR}/%.cmx: %.ml - ${ELIOMOPT} -c ${SERVER_INC} $(GENERATE_DEBUG) $< -${ELIOM_SERVER_DIR}/%.cmx: %.eliom - ${ELIOMOPT} -c ${SERVER_INC} $(GENERATE_DEBUG) $< - - -##---------------------------------------------------------------------- -## Client side compilation - -CLIENT_LIBS := ${addprefix -package ,${CLIENT_PACKAGES}} -CLIENT_INC := ${addprefix -package ,${CLIENT_PACKAGES}} - -CLIENT_OBJS := $(filter %.eliom %.ml, $(CLIENT_FILES)) -CLIENT_OBJS := $(patsubst %.eliom,${ELIOM_CLIENT_DIR}/%.cmo, ${CLIENT_OBJS}) -CLIENT_OBJS := $(patsubst %.ml,${ELIOM_CLIENT_DIR}/%.cmo, ${CLIENT_OBJS}) - -$(TEST_PREFIX)$(ELIOMSTATICDIR)/$(PROJECT_NAME).js: $(call objs,$(ELIOM_CLIENT_DIR),cmo,$(CLIENT_FILES)) | $(TEST_PREFIX)$(ELIOMSTATICDIR) - ${JS_OF_ELIOM} -o $@ $(GENERATE_DEBUG) $(CLIENT_INC) $(DEBUG_JS) \ - $(call depsort,$(ELIOM_CLIENT_DIR),cmo,-client,$(CLIENT_INC),$(CLIENT_FILES)) - -${ELIOM_CLIENT_DIR}/%.cmi: %.mli - ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< - -${ELIOM_CLIENT_DIR}/%.cmo: %.eliom - ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< -${ELIOM_CLIENT_DIR}/%.cmo: %.ml - ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< - -${ELIOM_CLIENT_DIR}/%.cmi: %.eliomi - ${JS_OF_ELIOM} -c ${CLIENT_INC} $(GENERATE_DEBUG) $< - -##---------------------------------------------------------------------- -## Dependencies - -include .depend - -.depend: $(patsubst %,$(DEPSDIR)/%.server,$(SERVER_FILES)) $(patsubst %,$(DEPSDIR)/%.client,$(CLIENT_FILES)) - cat $^ > $@ - -$(DEPSDIR)/%.server: % | $(DEPSDIR) - $(ELIOMDEP) -server -ppx $(SERVER_INC) $< > $@ - -$(DEPSDIR)/%.client: % | $(DEPSDIR) - $(ELIOMDEP) -client -ppx $(CLIENT_INC) $< > $@ - -$(DEPSDIR): - mkdir $@ - -##---------------------------------------------------------------------- -## Clean up - -clean: - -rm -f *.cm[ioax] *.cmxa *.cmxs *.o *.a *.annot - -rm -f *.type_mli - -rm -f ${PROJECT_NAME}.js - -rm -rf ${ELIOM_CLIENT_DIR} ${ELIOM_SERVER_DIR} - -distclean: clean - -rm -rf $(TEST_PREFIX) $(DEPSDIR) .depend +# Eliom default makefile +# Makefile.PROJECT_NAME is also included in this makefile +include Makefile.eliom diff --git a/simple/Makefile.options b/simple/Makefile.options index 42c4587..00c1cdc 100644 --- a/simple/Makefile.options +++ b/simple/Makefile.options @@ -1,59 +1,79 @@ #---------------------------------------------------------------------- # SETTINGS FOR THE ELIOM PROJECT graffiti #---------------------------------------------------------------------- +# Required binaries +OPAM := opam -PROJECT_NAME := graffiti +PROJECT_NAME := graffiti -# Source files for the server -SERVER_FILES := $(wildcard *.eliomi *.eliom) -# Source files for the client -CLIENT_FILES := $(wildcard *.eliomi *.eliom) +##---------------------------------------------------------------------- -# OCamlfind packages for the server -SERVER_PACKAGES := ocsigen-toolkit.server cairo2 unix js_of_ocaml-ppx_deriving_json -# OCamlfind packages for the client -CLIENT_PACKAGES := ocsigen-toolkit.client react js_of_ocaml-ppx \ - lwt_ppx js_of_ocaml-lwt js_of_ocaml-ppx_deriving_json +##---------------------------------------------------------------------- +## The following part contains the settings for the compilation process like the +## server/client OPAM packages and the server/client files. -# Directory with files to be statically served -LOCAL_STATIC = static +# OCamlfind packages for the server (for modules which defines services) +SERVER_ELIOM_PACKAGES := -# The backend for persistent data. Can be dbm or sqlite. -PERSISTENT_DATA_BACKEND = dbm +# OCamlfind packages for the server +SERVER_PACKAGES := -# Debug application (yes/no): Debugging info in compilation, -# JavaScript, ocsigenserver -DEBUG := no +##---------------------------------------------------------------------- + +##---------------------------------------------------------------------- +## The following part contains the configuration for the ocsigenserver. # User to run server with (make run.*) -WWWUSER ?= www-data -WWWGROUP ?= www-data +WWWUSER := www-data +WWWGROUP := www-data # Port for running the server (make run.*) -PORT := 80 +PORT := 80 # Port for testing (make test.*) -TEST_PORT := 8080 +TEST_PORT := 8080 # Root of installation (must end with /) -PREFIX ?= /usr/local/ +PREFIX := /usr/local/ # Local folder for make test.* (must end with /) -TEST_PREFIX := local/ +TEST_PREFIX := local/ + +## The installation tree (relative to $(PREFIX) when installing/running or +## $(TEST_PREFIX) when testing). -# The installation tree (relative to $(PREFIX) when -# installing/running or $(TEST_PREFIX) when testing). # Configuration file $(PROJECT_NAME).conf -ETCDIR := etc/${PROJECT_NAME} +ETCDIR := etc/${PROJECT_NAME} + # Project's library $(PROJECT_NAME).cma (cmxs) -LIBDIR := lib/${PROJECT_NAME} +LIBDIR := lib/${PROJECT_NAME} + # Command pipe, eg. $ echo restart > $(INSTALL_PREFIX)$(CMDPIPE) -CMDPIPE := var/run/${PROJECT_NAME}-cmd +CMDPIPE := var/run/${PROJECT_NAME}-cmd + # Ocsigenserver's logging files -LOGDIR := var/log/${PROJECT_NAME} +LOGDIR := var/log/${PROJECT_NAME} + # Ocsigenserver's persistent data files -DATADIR := var/data/${PROJECT_NAME} -# Copy of $(LOCAL_STATIC) -STATICDIR := var/www/${PROJECT_NAME}/static -# Project's JavaScript file -ELIOMSTATICDIR := var/www/${PROJECT_NAME}/eliom +DATADIR := var/data/${PROJECT_NAME} + +# Project's static files +FILESDIR := var/www/${PROJECT_NAME} + +# Project's JavaScript file directory +ELIOMSTATICDIR := var/www/${PROJECT_NAME} + +LOCAL_STATIC := static +LOCAL_STATIC_CSS := $(LOCAL_STATIC)/css +CSS_PREFIX := $(LOCAL_STATIC_CSS)/${PROJECT_NAME} +##---------------------------------------------------------------------- + + +##---------------------------------------------------------------------- +## The following part contains the settings for debugging + +# Debug application (yes/no): Debugging info in compilation, +# JavaScript, ocsigenserver +DEBUG := yes + +##---------------------------------------------------------------------- diff --git a/simple/README b/simple/README.md similarity index 68% rename from simple/README rename to simple/README.md index a83fc9e..686eb71 100644 --- a/simple/README +++ b/simple/README.md @@ -1,13 +1,8 @@ - Instructions ============ -This project is (initially) generated by eliom-distillery as the basic -project "graffiti". - -Generally, you can compile it and run ocsigenserver on it by - $ make test.byte (or test.opt) -See below for other useful targets for make. +This project is (initially) generated by `eliom-distillery` as the basic +project `graffiti`. Generated files --------------- @@ -17,16 +12,13 @@ eliom-distillery: - graffiti.eliom This is your initial source file. - All Eliom files (*.eliom, *.eliomi) in this directory are - automatically considered. To add a .ml/.mli file to your project, - append it to the variable SERVER_FILES or CLIENT_FILES. - static/ The content of this folder is statically served. Put your CSS or - additional JavaScript files here! + additional JavaScript files here - Makefile.options - Configure your project here! + Configure your project here - graffiti.conf.in This file is a template for the configuration file for @@ -40,8 +32,10 @@ eliom-distillery: Eliom application. You better don't touch it ;) See below for the relevant targets. - - README - Not completely describable here. + - local/ + This directory is the target of the temporary installation of + your application, to test locally before doing a system-wide + installation in /. Do not put anything manually here. Makefile targets @@ -65,7 +59,3 @@ Here's some help on how to work with this basic distillery project: `sudo'. If Eliom isn't installed globally, however, you need to re-export some environment variables to make this work: $ sudo PATH=$PATH OCAMLPATH=$OCAMLPATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH make run.byte/run.opt - - - If you need a findlib package in your project, add it to the - variables SERVER_PACKAGES and/or CLIENT_PACKAGES. The configuration - file will be automatically updated. diff --git a/simple/dune b/simple/dune new file mode 100644 index 0000000..7ea47ac --- /dev/null +++ b/simple/dune @@ -0,0 +1,32 @@ +(dirs tools client assets) + +(executables + (names graffiti) + (modes (byte plugin) (native plugin)) + (libraries eliom.server ocsipersist.dbm cairo2 ocsigen-toolkit.server) + (preprocess + (pps + lwt_ppx + pgocaml_ppx + js_of_ocaml-ppx_deriving_json + ocsigen-i18n + ocsigen-ppx-rpc --rpc-raw + eliom.ppx.server + -- --prefix Graffiti_ --suffix _i18n --default-module Graffiti_i18n + ) + ) + ) + +(rule (target graffiti_i18n.eliom) (deps assets/graffiti_i18n.tsv) + (action + (with-stdout-to %{target} + (with-stdin-from %{deps} + (pipe-stdout + (run ocsigen-i18n-generator --languages en,fr --default-language fr %{deps}) + (run sed "1 s/]/[@@deriving json]]\\n[%%shared [@@@ocaml.warning\"-27\"]]/")))))) + +(rule (alias graffiti) + (deps graffiti.cma client/graffiti.bc client/graffiti.bc.js tools/check_modules.ml) + (action (run ocaml tools/check_modules.ml graffiti))) + +(env (_ (flags (:standard -w -9-37-39)))) diff --git a/simple/dune-project b/simple/dune-project new file mode 100644 index 0000000..671e67b --- /dev/null +++ b/simple/dune-project @@ -0,0 +1,10 @@ +(lang dune 3.0) + +(dialect + (name "eliom-server") + (implementation (extension "eliom")) + (interface (extension "eliomi"))) + +(wrapped_executables false) + +(formatting (enabled_for ocaml "eliom-server")) diff --git a/simple/graffiti.conf.in b/simple/graffiti.conf.in index 5a82319..24c5396 100644 --- a/simple/graffiti.conf.in +++ b/simple/graffiti.conf.in @@ -14,8 +14,10 @@ %%DEBUGMODE%% %%CMDPIPE%% - + + + %%% This will include the packages defined as SERVER_PACKAGES in your Makefile: %%PACKAGES%% diff --git a/simple/graffiti.eliom b/simple/graffiti.eliom index b93c9a8..1e0a7e8 100644 --- a/simple/graffiti.eliom +++ b/simple/graffiti.eliom @@ -19,7 +19,7 @@ *) open%shared Eliom_content -open%shared Js_of_ocaml +open%client Js_of_ocaml open%client Js_of_ocaml_lwt module%server Graffiti_app = @@ -29,8 +29,8 @@ module%server Graffiti_app = let global_data_path = None end) -let%shared width = 700 -let%shared height = 400 +let%server width = 700 +let%server height = 400 type%shared messages = ((int * int * int) * int * (int * int) * (int * int)) [@@deriving json] @@ -127,7 +127,7 @@ let%client init_client ~cp_sig () = ~src:(Html.D.make_uri ~service:~%imageservice ()) ()) in - img##.onload := Dom_html.handler (fun ev -> + img##.onload := Dom_html.handler (fun _ev -> ctx##drawImage img 0. 0.; Js._false); let x = ref 0 and y = ref 0 in @@ -165,9 +165,9 @@ let%client init_client ~cp_sig () = [mousemoves Dom_html.document (fun x _ -> line x); let%lwt ev = mouseup Dom_html.document in line ev])); - Lwt.async (fun () -> Lwt_stream.iter (draw ctx) (Eliom_bus.stream ~%bus)) + Lwt.async (fun () -> Lwt_stream.iter (draw ctx) (Eliom_bus.stream ~%(bus : (messages, messages) Eliom_bus.t))) -let%server main_service = +let%server _main_service = Graffiti_app.create ~path:(Eliom_service.Path [""]) ~meth:(Eliom_service.Get Eliom_parameter.unit) diff --git a/simple/static/css/ot_color_picker.css b/simple/static/css/ot_color_picker.css new file mode 100644 index 0000000..3571be2 --- /dev/null +++ b/simple/static/css/ot_color_picker.css @@ -0,0 +1,43 @@ +.ot-color-picker-selected-cell { + z-index: 2; + border: 2px solid black; + margin: -2px -2px -2px -2px; + box-shadow: 0 0 15px white; +} + +.ot-color-picker-hue-picker { + display: flex; + width: 100%; + flex-direction: row; + margin-bottom: 10px; + flex: 1; +} + +.ot-color-picker-hue-picker-cell { + flex: 1; + height: 100%; +} + +.ot-color-picker-sl-picker { + display: flex; + flex-direction: column; + flex: 9; + margin: 1px; +} + +.ot-color-picker-sl-picker-row { + display: flex; + flex-direction: row; + flex: 1; +} + +.ot-color-picker-sl-picker-cell { + flex: 1; + height: 100%; +} + +.ot-color-picker { + display: flex; + flex-direction: column; + height: 100%; +} diff --git a/simple/tools/check_modules.ml b/simple/tools/check_modules.ml new file mode 100644 index 0000000..d95d415 --- /dev/null +++ b/simple/tools/check_modules.ml @@ -0,0 +1,102 @@ +#load "unix.cma" + +#load "str.cma" + +let app = Sys.argv.(1) + +let modules_from_bytecode_executable nm = + let ch = Unix.open_process_in (Printf.sprintf "ocamlobjinfo %s" nm) in + while input_line ch <> "Imported units:" do + () + done; + let lst = ref [] in + (try + while + let l = input_line ch in + if l <> "" && l.[0] = '\t' + then ( + let i = String.rindex l '\t' in + lst := String.sub l (i + 1) (String.length l - i - 1) :: !lst; + true) + else false + do + () + done + with End_of_file -> ()); + !lst + +let modules_from_bytecode_library nm = + let ch = Unix.open_process_in (Printf.sprintf "ocamlobjinfo %s" nm) in + let lst = ref [] in + (try + while true do + let l = input_line ch in + if String.length l > 11 && String.sub l 0 11 = "Unit name: " + then lst := String.sub l 11 (String.length l - 11) :: !lst + done + with End_of_file -> ()); + !lst + +let read_file f = + let ch = open_in f in + let s = really_input_string ch (in_channel_length ch) in + close_in ch; s + +let section_re = Str.regexp "close_\\(server\\|client\\)_section" + +let match_substring sub_re s = + try + ignore (Str.search_forward sub_re s 0); + true + with Not_found -> false + +let eliom_modules dir = + Sys.readdir dir |> Array.to_list |> List.sort compare + |> List.filter_map @@ fun nm -> + if Filename.check_suffix nm ".pp.eliom" + then + let f = read_file (Filename.concat dir nm) in + Some + ( String.capitalize_ascii (Filename.chop_suffix nm ".pp.eliom") + , match_substring section_re f ) + else None + +let print_modules side l = + Format.printf "[%%%%%s.start]@.@." side; + List.iter (fun m -> Format.printf "module %s = %s@." m m) l; + Format.printf "@." + +let _ = + let client_modules = + modules_from_bytecode_executable (Printf.sprintf "./client/%s.bc" app) + in + let server_modules = + modules_from_bytecode_library (Printf.sprintf "./%s.cma" app) + in + let eliom_modules = eliom_modules "." in + let missing_server_modules = + List.filter_map + (fun (m, sect) -> + let c = List.mem m client_modules in + let s = List.mem m server_modules in + match c, s, sect with true, false, true -> Some m | _ -> None) + eliom_modules + in + let missing_client_modules = + List.filter_map + (fun (m, sect) -> + let c = List.mem m client_modules in + let s = List.mem m server_modules in + match c, s, sect with false, true, true -> Some m | _ -> None) + eliom_modules + in + let missing_modules = + missing_server_modules <> [] || missing_client_modules <> [] + in + if missing_modules + then Format.eprintf "Some modules are missing in %s.eliom:@.@." app; + if missing_server_modules <> [] + then print_modules "server" missing_server_modules; + if missing_client_modules <> [] + then print_modules "client" missing_client_modules; + if missing_modules then exit 1 diff --git a/simple/tools/dune b/simple/tools/dune new file mode 100644 index 0000000..adacc55 --- /dev/null +++ b/simple/tools/dune @@ -0,0 +1,10 @@ +(executable + (name eliom_ppx_client) + (modes native) + (modules eliom_ppx_client) + (preprocess (pps lwt_ppx)) + (libraries ocsigen-ppx-rpc eliom.ppx.client)) + +(rule + (action (with-stdout-to eliom_ppx_client.ml + (echo "let () = Ppxlib.Driver.standalone ()")))) diff --git a/simple/tools/gen_dune.ml b/simple/tools/gen_dune.ml new file mode 100644 index 0000000..41b588f --- /dev/null +++ b/simple/tools/gen_dune.ml @@ -0,0 +1,29 @@ +let with_suffixes nm l f = + List.iter + (fun suffix -> + if Filename.check_suffix nm suffix + then f (Filename.chop_suffix nm suffix)) + l + +let handle_file_client nm = + if Filename.check_suffix nm ".pp.eliom" + then () + else if Filename.check_suffix nm ".pp.eliomi" + then () + else + with_suffixes nm [".eliom"; ".tsv"] (fun nm -> + Printf.printf + "(rule (target %s.ml) (deps ../%s.eliom)\n\ (action\n\ (with-stdout-to %%{target}\n\ (chdir .. (run tools/eliom_ppx_client.exe --as-pp -server-cmo %%{cmo:../%s} --impl %s.eliom)))))\n" + nm nm nm nm); + if Filename.check_suffix nm ".eliomi" + then + let nm = Filename.chop_suffix nm ".eliomi" in + Printf.printf + "(rule (target %s.mli) (deps ../%s.eliomi)\n\ (action\n\ (with-stdout-to %%{target}\n\ (chdir .. (run tools/eliom_ppx_client.exe --as-pp --intf %%{deps})))))\n" + nm nm + +let () = + Array.concat (List.map Sys.readdir ["."; "./assets"]) + |> Array.to_list |> List.sort compare + |> List.filter (fun nm -> nm.[0] <> '.') + |> List.iter handle_file_client diff --git a/simple/tools/sort_deps.ml b/simple/tools/sort_deps.ml new file mode 100644 index 0000000..1547a64 --- /dev/null +++ b/simple/tools/sort_deps.ml @@ -0,0 +1,73 @@ +#load "str.cma" + +let space_re = Str.regexp " +" +let edges = Hashtbl.create 128 +let edge_count = Hashtbl.create 128 + +let chop s = + try + let i = String.rindex s '.' in + String.sub s 0 i + with Not_found -> s + +let add_edge target dep = + if target <> dep + then ( + Hashtbl.replace edges dep + (target :: (try Hashtbl.find edges dep with Not_found -> [])); + Hashtbl.replace edge_count target + (1 + try Hashtbl.find edge_count target with Not_found -> 0); + if not (Hashtbl.mem edge_count dep) then Hashtbl.add edge_count dep 0) + +let sort l = + let res = ref [] in + List.iter + (fun (target, deps) -> + let target = chop target in + if not (Hashtbl.mem edge_count target) + then Hashtbl.add edge_count target 0; + List.iter (fun dep -> add_edge target (chop dep)) deps) + l; + let q = Queue.create () in + Hashtbl.iter + (fun target count -> if count = 0 then Queue.add target q) + edge_count; + while not (Queue.is_empty q) do + let n = Queue.take q in + res := n :: !res; + let l = try Hashtbl.find edges n with Not_found -> [] in + Hashtbl.remove edges n; + List.iter + (fun target -> + let c = Hashtbl.find edge_count target - 1 in + Hashtbl.replace edge_count target c; + if c = 0 then Queue.add target q) + l + done; + if Hashtbl.length edges <> 0 + then ( + Format.eprintf "Dependency loop!@."; + exit 1); + List.rev !res + +let _ = + let ch = open_in Sys.argv.(1) in + let lst = ref [] in + (try + while true do + let l = input_line ch in + let l = Str.split space_re l in + match l with + | target :: ":" :: deps -> lst := (target, deps) :: !lst + | _ -> assert false + done + with End_of_file -> ()); + let lst = sort !lst in + let files = Hashtbl.create 128 in + for i = 2 to Array.length Sys.argv - 1 do + Hashtbl.add files (chop Sys.argv.(i)) Sys.argv.(i) + done; + List.iter + (fun f -> + try Format.printf "%s@." (Hashtbl.find files f) with Not_found -> ()) + lst