Browse Source

use scfg configuration file, improve generated files

master
zapashcanon 5 months ago
parent
commit
863736b22b
Signed by: zapashcanon GPG Key ID: 8981C3C62D1D28F1
  1. 25
      .ocamlformat
  2. 6
      dune-project
  3. 2
      gotd.opam
  4. 62
      src/config.ml
  5. 4
      src/dune
  6. 117
      src/gotd.ml
  7. 89
      src/mk.ml

25
.ocamlformat

@ -1,51 +1,34 @@
version=0.19.0
align-cases=false
align-constructors-decl=false
align-variants-decl=false
version=0.20.1
assignment-operator=end-line
break-before-in=fit-or-vertical
break-cases=all
break-collection-expressions=fit-or-vertical
break-cases=fit
break-fun-decl=wrap
break-fun-sig=wrap
break-infix=wrap
break-infix-before-func=false
break-separators=before
break-sequences=true
break-string-literals=auto
break-struct=force
cases-exp-indent=2
cases-matching-exp-indent=normal
disambiguate-non-breaking-match=false
doc-comments=before
doc-comments-padding=2
doc-comments-tag-only=default
dock-collection-brackets=false
exp-grouping=preserve
extension-indent=2
field-space=loose
function-indent=2
function-indent-nested=never
if-then-else=k-r
indent-after-in=0
if-then-else=compact
indicate-multiline-delimiters=space
indicate-nested-or-patterns=unsafe-no
infix-precedence=indent
leading-nested-match-parens=false
let-and=sparse
let-binding-indent=2
let-binding-spacing=compact
let-module=compact
margin=80
match-indent=0
match-indent-nested=never
max-indent=68
module-item-spacing=sparse
nested-match=wrap
ocp-indent-compat=false
parens-ite=false
parens-tuple=always
parens-tuple-patterns=multi-line-only
parse-docstrings=true
sequence-blank-line=preserve-one
sequence-style=terminator
@ -54,8 +37,6 @@ space-around-arrays=true
space-around-lists=true
space-around-records=true
space-around-variants=true
stritem-extension-indent=0
type-decl=sparse
type-decl-indent=2
wrap-comments=false
wrap-fun-args=true

6
dune-project

@ -1,5 +1,7 @@
(lang dune 2.8)
(implicit_transitive_deps false)
(name gotd)
(license ISC)
@ -10,4 +12,6 @@
(name gotd)
(depends
(ocaml
(>= 4.08))))
(>= 4.08))
directories
scfg))

2
gotd.opam

@ -4,6 +4,8 @@ license: "ISC"
depends: [
"dune" {>= "2.8"}
"ocaml" {>= "4.08"}
"directories"
"scfg"
"odoc" {with-doc}
]
build: [

62
src/config.ml

@ -0,0 +1,62 @@
module Dirs = Directories.Project_dirs (struct
let qualifier = "fr"
let organization = "zapashcanon"
let application = "gotd"
end)
let user_config =
match Dirs.config_dir with
| None ->
Format.eprintf "can't compute user configuration directory path@.";
None
| Some config_dir ->
let filename = Filename.concat config_dir "config.scfg" in
if Sys.file_exists filename then
match Scfg.Parse.from_file filename with
| Error e ->
Format.eprintf "error while parsing configuration file: %s@." e;
None
| Ok config -> Some config
else begin
Format.eprintf "configuration file %s doesn't exist@." filename;
None
end
let get0 dir default =
let dir = Option.bind user_config (Scfg.Query.get_dir dir) in
let param = Option.map (Scfg.Query.get_param 0) dir in
Option.value (Option.bind param Result.to_option) ~default
let author = get0 "author" "TODO"
let bug_prefix = get0 "bug_prefix" "TODO/"
let bug_suffix = get0 "bug_suffix" ""
let doc_prefix = get0 "doc_prefix" "TODO/"
let doc_suffix = get0 "doc_suffix" ""
let homepage_prefix = get0 "homepage_prefix" "TODO/"
let homepage_suffix = get0 "homepage_suffix" ""
let maintainer = get0 "maintainer" "TODO"
let source_prefix = get0 "source_prefix" "TODO/"
let source_suffix = get0 "source_suffix" ""
let () =
Format.eprintf "using author %s@." author;
Format.eprintf "using bug prefix %s@." bug_prefix;
Format.eprintf "using bug suffix %s@." bug_suffix;
Format.eprintf "using doc prefix %s@." doc_prefix;
Format.eprintf "using doc suffix %s@." doc_suffix;
Format.eprintf "using homepage prefix %s@." homepage_prefix;
Format.eprintf "using homepage suffix %s@." homepage_suffix;
Format.eprintf "using maintainer %s@." maintainer;
Format.eprintf "using source prefix %s@." source_prefix;
Format.eprintf "using source suffix %s@." source_suffix

4
src/dune

@ -1,4 +1,4 @@
(executable
(public_name gotd)
(modules default gotd)
(libraries bos directories fpath))
(modules config mk gotd)
(libraries bos directories fpath scfg))

117
src/gotd.ml

@ -1,3 +1,5 @@
open Fpath
let error msg =
Format.eprintf "error: %s@." msg;
exit 1
@ -5,110 +7,55 @@ let error msg =
let log msg = Format.eprintf "%s@." msg
let gen_file path default =
log @@ Format.asprintf "creating file %a" Fpath.pp path;
log @@ Format.asprintf "creating file %a" Fpath.pp path;
match Bos.OS.File.write ~mode:0o644 path default with
| Ok () -> ()
| Error (`Msg _) -> error @@ Format.asprintf "can't write %a" Fpath.pp path
let gen_dir path =
log @@ Format.asprintf "creating directory %a" Fpath.pp path;
log @@ Format.asprintf "creating directory %a" Fpath.pp path;
match Bos.OS.Dir.create ~path:false ~mode:0o755 path with
| Ok true -> ()
| Ok false
| Error (`Msg _) ->
| Ok false | Error (`Msg _) ->
error @@ Format.asprintf "can't create directory %a" Fpath.pp path
module Dirs = Directories.Project_dirs (struct
let qualifier = "fr"
let organization = "zapashcanon"
let application = "gotd"
end)
let () =
if Array.length Sys.argv <> 2 then
error @@ Format.sprintf "usage: %s <project name>" Sys.argv.(0)
let project_name = Sys.argv.(1)
let root = Fpath.v project_name
(* TODO: check with Bos.OS.Path.exists root first ? If a file named root exists this may cause issue otherwise... *)
let () = gen_dir root
let gitignore = Fpath.(root // v ".gitignore")
let () = gen_file gitignore Default.gitignore
let license = Fpath.(root // v "LICENSE.md")
let () = gen_file license (Default.license Default.author)
let readme = Fpath.(root // v "README.md")
let () = gen_file readme (Default.readme project_name)
let changes = Fpath.(root // v "CHANGES.md")
let () = gen_file changes Default.changes
let ocamlformat = Fpath.(root // v ".ocamlformat")
let () = gen_file ocamlformat Default.ocamlformat
let duneproject = Fpath.(root // v "dune-project")
let () = gen_file duneproject (Default.duneproject project_name)
let src = Fpath.(root // v "src")
let () = gen_dir src
let root = v project_name
let src_dune = Fpath.(src // v "dune")
let src = root // v "src"
let () = gen_file src_dune (Default.src_dune project_name)
let doc = root // v "doc"
let src_name = Fpath.(src // add_ext "ml" (v project_name))
let example = root // v "example"
let () = gen_file src_name Default.src_name
let test = root // v "test"
let doc = Fpath.(root // v "doc")
let () = gen_dir doc
let doc_dune = Fpath.(doc // v "dune")
let () = gen_file doc_dune (Default.doc_dune project_name)
let doc_index = Fpath.(doc // v "index.mld")
let () = gen_file doc_index (Default.doc_index project_name)
let example = Fpath.(root // v "example")
let () = gen_dir example
let example_dune = Fpath.(example // v "dune")
let () = gen_file example_dune Default.example_dune
let example_main = Fpath.(example // v "main.ml")
let () = gen_file example_main Default.example_main
let test = Fpath.(root // v "test")
let () = gen_dir test
let test_dune = Fpath.(test // v "dune")
let () = gen_file test_dune Default.test_dune
let test_main = Fpath.(test // v "main.ml")
let () = gen_file test_main Default.test_main
let () = log "done ! happy hacking 🐱"
let () =
(* TODO: check with Bos.OS.Path.exists root first ? If a file named root exists this may cause issue otherwise... *)
gen_dir root;
gen_file (root // v ".gitignore") Mk.gitignore;
gen_file (root // v "LICENSE.md") Mk.license;
gen_file (root // v "README.md") (Mk.readme project_name);
gen_file (root // v "CHANGES.md") Mk.changes;
gen_file (root // v ".ocamlformat") Mk.ocamlformat;
gen_file (root // v "dune-project") (Mk.duneproject project_name);
gen_dir src;
gen_file (src // v "dune") (Mk.src_dune project_name);
gen_file (src // add_ext "ml" (v project_name)) Mk.src_name;
gen_dir doc;
gen_file (doc // v "dune") (Mk.doc_dune project_name);
gen_file (doc // v "index.mld") (Mk.doc_index project_name);
gen_dir example;
gen_file (example // v "dune") Mk.example_dune;
gen_file (example // v "main.ml") Mk.example_main;
gen_dir test;
gen_file (test // v "dune") Mk.test_dune;
gen_file (test // v "test.ml") Mk.test_test;
log "done ! happy hacking 🐱"

89
src/default.ml → src/mk.ml

@ -1,4 +1,4 @@
let author = "TODO"
open Config
let changes = {|## unreleased
|}
@ -13,16 +13,14 @@ let doc_index name =
Format.sprintf
{|{0 %s}
{{:https://TODO} %s} is an {{:https://ocaml.org} OCaml} library/executable to TODO.
{{:https://%s%s} %s} is an {{:https://ocaml.org} OCaml} library/executable to TODO.
{1:api API}
{!modules:
%s
}
{1:private_api Private API}
You shouldn't have to use any of these modules, they're used internally only.
@ -31,44 +29,47 @@ You shouldn't have to use any of these modules, they're used internally only.
TODO
}
|}
name name
(String.mapi
(fun i c ->
if i = 0 then
Char.uppercase_ascii c
else
c )
name )
name homepage_prefix name name
(String.mapi (fun i c -> if i = 0 then Char.uppercase_ascii c else c) name)
let gitignore = "_build\n"
let license author =
let license =
let year = (Unix.localtime @@ Unix.gettimeofday ()).tm_year + 1900 in
Format.sprintf
{|The ISC License (ISC)
=====================
Copyright © 2021, %s
Copyright © %d, %s
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|}
author
year author
let duneproject name =
Format.sprintf
{|(lang dune 2.8)
{|(lang dune 2.9)
(implicit_transitive_deps false)
(name %s)
(license ISC)
(authors "TODO")
(authors "%s")
(maintainers "%s")
(maintainers "TODO")
(source
(uri %s%s%s))
;(source
; (github TODO/%s))
(homepage %s%s%s)
(bug_reports %s%s%s)
(documentation %s%s%s)
(generate_opam_files true)
@ -83,7 +84,9 @@ let duneproject name =
(ocaml
(>= 4.08))))
|}
name name name name name
name author maintainer source_prefix name source_suffix homepage_prefix name
homepage_suffix bug_prefix name bug_suffix doc_prefix name doc_suffix name
name name
let example_dune = {|(executable
(name main)
@ -94,54 +97,37 @@ let example_main = {|let () = Format.printf "TODO@."
|}
let ocamlformat =
{|version=0.19.0
align-cases=false
align-constructors-decl=false
align-variants-decl=false
{|version=0.20.1
assignment-operator=end-line
break-before-in=fit-or-vertical
break-cases=all
break-collection-expressions=fit-or-vertical
break-cases=fit
break-fun-decl=wrap
break-fun-sig=wrap
break-infix=wrap
break-infix-before-func=false
break-separators=before
break-sequences=true
break-string-literals=auto
break-struct=force
cases-exp-indent=2
cases-matching-exp-indent=normal
disambiguate-non-breaking-match=false
doc-comments=before
doc-comments-padding=2
doc-comments-tag-only=default
dock-collection-brackets=false
exp-grouping=preserve
extension-indent=2
field-space=loose
function-indent=2
function-indent-nested=never
if-then-else=k-r
indent-after-in=0
if-then-else=compact
indicate-multiline-delimiters=space
indicate-nested-or-patterns=unsafe-no
infix-precedence=indent
leading-nested-match-parens=false
let-and=sparse
let-binding-indent=2
let-binding-spacing=compact
let-module=compact
margin=80
match-indent=0
match-indent-nested=never
max-indent=68
module-item-spacing=sparse
nested-match=wrap
ocp-indent-compat=false
parens-ite=false
parens-tuple=always
parens-tuple-patterns=multi-line-only
parse-docstrings=true
sequence-blank-line=preserve-one
sequence-style=terminator
@ -150,9 +136,7 @@ space-around-arrays=true
space-around-lists=true
space-around-records=true
space-around-variants=true
stritem-extension-indent=0
type-decl=sparse
type-decl-indent=2
wrap-comments=false
wrap-fun-args=true
|}
@ -161,7 +145,7 @@ let readme name =
Format.sprintf
{|# %s
%s is an [OCaml] executable/library to TODO.
[%s] is an [OCaml] executable/library to TODO.
## Installation
@ -189,18 +173,19 @@ For more, have a look at the [example] folder, at the [documentation] or at the
- [CHANGELOG]
[CHANGELOG]: ./CHANGES.md
[example]: ./example/
[example]: ./example
[LICENSE]: ./LICENSE.md
[opam file]: ./%s.opam
[test suite]: ./test/
[test suite]: ./test
[documentation]: TODO
[documentation]: %s%s%s
[how to install opam]: https://opam.ocaml.org/doc/Install.html
[OCaml]: https://ocaml.org
[opam]: https://opam.ocaml.org/
[%s]: TODO
[%s]: %s%s%s
|}
name name name name name name
name name name name name doc_prefix name doc_suffix name homepage_prefix
name homepage_suffix
let src_dune name =
Format.sprintf {|(executable
@ -211,9 +196,9 @@ let src_name = {|let () = Format.printf "Hello!@."
|}
let test_dune = {|(test
(name main)
(modules main))
(name test)
(modules test))
|}
let test_main = {|let () = assert true (* TODO *)
let test_test = {|let () = assert true (* TODO *)
|}
Loading…
Cancel
Save