package spin

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file ppx.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(* Generated by: ocaml-crunch
   Creation date: Sat, 17 May 2025 18:04:16 GMT *)

module Internal = struct
  let d_02ef1536addcb2e5f1f36b2fcd537fb1 = "#!/usr/bin/env node\n\nconst path = require(\"path\");\nconst cp = require(\"child_process\");\nconst fs = require(\"fs\");\n\nconst platform = process.platform;\n\nconst binariesToCopy = [\n  \"{{ project_slug }}\"\n];\n\nfunction find_arch() {\n  // The running binary is 64-bit, so the OS is clearly 64-bit.\n  if (process.arch === \"x64\") {\n    return \"x64\";\n  }\n\n  // All recent versions of Mac OS are 64-bit.\n  if (process.platform === \"darwin\") {\n    return \"x64\";\n  }\n\n  // On Windows, the most reliable way to detect a 64-bit OS from within a 32-bit\n  // app is based on the presence of a WOW64 file: %SystemRoot%\\SysNative.\n  // See: https://twitter.com/feross/status/776949077208510464\n  if (process.platform === \"win32\") {\n    var useEnv = false;\n    try {\n      useEnv = !!(process.env.SYSTEMROOT && fs.statSync(process.env.SYSTEMROOT));\n    } catch (err) { }\n\n    const sysRoot = useEnv ? process.env.SYSTEMROOT : \"C:\\\\Windows\";\n\n    // If %SystemRoot%\\SysNative exists, we are in a WOW64 FS Redirected application.\n    const isWOW64 = false;\n    try {\n      isWOW64 = !!fs.statSync(path.join(sysRoot, \"sysnative\"));\n    } catch (err) { }\n\n    return isWOW64 ? \"x64\" : \"x86\";\n  }\n\n  if (process.platform === \"linux\") {\n    const output = cp.execSync(\"getconf LONG_BIT\", { encoding: \"utf8\" });\n    return output === \"64\\n\" ? \"x64\" : \"x86\";\n  }\n\n  return \"x86\";\n}\n\n// Implementing it b/c we don\"t want to depend on fs.copyFileSync which appears only in node@8.x\nfunction copyFileSync(sourcePath, destPath) {\n  const data = fs.readFileSync(sourcePath);\n  const stat = fs.statSync(sourcePath);\n  fs.writeFileSync(destPath, data);\n  fs.chmodSync(destPath, stat.mode);\n}\n\nconst copyPlatformBinaries = platformPath => {\n  const platformBuildPath = path.join(__dirname, platformPath);\n\n  binariesToCopy.forEach(binaryPath => {\n    const sourcePath = path.join(platformBuildPath, binaryPath);\n    const destPath = path.join(__dirname, binaryPath);\n    if (fs.existsSync(destPath)) {\n      fs.unlinkSync(destPath);\n    }\n    copyFileSync(sourcePath, destPath);\n    fs.chmodSync(destPath, 0o755);\n  });\n};\n\nconst arch = find_arch();\n\nconst platformPath = \"platform-\" + platform + \"-\" + arch;\nconst supported = fs.existsSync(platformPath);\n\nif (!supported) {\n  console.error(\"{{ project_name }} does not support this platform :(\");\n  console.error(\"\");\n  console.error(\"If you want {{ project_name }} to support this platform natively,\");\n  console.error(\"please open an issue at our repository, linked above.\");\n  console.error(\"Specify that you are on the \" + platform + \" platform,\");\n  console.error(\"and on the \" + arch + \" architecture.\");\n  process.exit(1);\n}\n\ncopyPlatformBinaries(platformPath);\n"

  let d_0a98aa2defed3dc469f91f8ffa5b5d73 = "(lang dune 2.0)\n(name {{ project_slug }})\n(source (github {{ github_username }}/{{ project_slug }}))\n(license MIT)\n(authors \"{{ username }}{% if author_email %} <{{ author_email }}>{% endif %}\")\n(maintainers \"{{ username }}{% if author_email %} <{{ author_email }}>{% endif %}\")\n\n(generate_opam_files true)\n\n(package\n (name {{ project_slug }})\n (synopsis \"{{ project_description }}\")\n (description \"\\\n{{ project_description }}\n\")\n (depends\n  (ocaml (>= 4.08.0))\n  (dune (>= 2.0))\n  {%- if test_framework == 'Rely' %}\n  ; Add Rely when released on Opam\n  ; (rely :with-test)\n  {%- else %}\n  (alcotest :with-test)\n  {%- endif %}\n  (odoc :with-doc)\n  {%- if syntax == 'Reason' %}\n  (reason :build)\n  {%- endif %}\n  (ppxlib :build)))\n"

  let d_1bf06103822114388bfcdf983af7c5cc = "# This file is generated by dune, edit dune-project instead\nopam-version: \"2.0\"\nsynopsis: \"{{ project_description }}\"\ndescription: \"\"\"\n{{ project_description }}\n\"\"\"\nmaintainer: [\"{{ username }}{% if author_email %} <{{ author_email }}>{% endif %}\"]\nauthors: [\"{{ username }}{% if author_email %} <{{ author_email }}>{% endif %}\"]\nlicense: \"MIT\"\nhomepage: \"https://github.com/{{ github_username }}/{{ project_slug }}\"\ndoc: \"https://{{ github_username }}.github.io/{{ project_slug }}\"\nbug-reports: \"https://github.com/{{ github_username }}/{{ project_slug }}/issues\"\ndepends: [\n  \"ocaml\" {>= \"4.08.0\"}\n  \"dune\" {>= \"2.0\"}\n  {% if test_framework == 'Alcotest' -%}\n  \"alcotest\" {with-test}\n  {% endif -%}\n  \"odoc\" {with-doc}\n  {% if syntax == 'Reason' -%}\n  \"reason\" {build}\n  {% endif -%}\n  \"ppxlib\" {build}\n]\nbuild: [\n  [\"dune\" \"subst\"] {pinned}\n  [\n    \"dune\"\n    \"build\"\n    \"-p\"\n    name\n    \"-j\"\n    jobs\n    \"@install\"\n    \"@runtest\" {with-test}\n    \"@doc\" {with-doc}\n  ]\n]\ndev-repo: \"git+https://github.com/{{ github_username }}/{{ project_slug }}.git\"\n"

  let d_22a4a727f14480a70c5b0ab38d5c0d99 = "(executable\n (name main)\n (public_name {{ project_slug }})\n (libraries {{ project_snake }} cmdliner fmt fmt.tty logs.fmt logs.cli)\n (flags (:standard -open StdLabels)))\n\n(include_subdirs unqualified)\n"

  let d_3e9e22e70747fd748b90579a40a678ec = "# PPX\n\nPPX library with prebuilt binaries for native and bucklescript.\n\n```bash\nspin new ppx\n```\n\n## Acknowledgments\n\nThis template is inspired by these awesome projects:\n\n- [hello-ppx-esy](https://github.com/jchavarri/hello-ppx-esy) - A simple example of a ppx with Reason and esy\n- [ppx-examples](https://github.com/ttinythings/ppx-examples/) - PPX Examples written with ReasonML and Ppxlib"

  let d_4025396dfb5871ced6b8051264e10553 = "// @flow\n\nconst { execSync } = require(\"child_process\");\nconst fs = require(\"fs\");\nconst path = require(\"path\");\nconst package = require(\"../package.json\");\n\nconst filesToCopy = [\"LICENSE\", \"README.md\", \"CHANGES.md\"];\n\nfunction exec(cmd) {\n  console.log(`exec: ${cmd}`);\n  return execSync(cmd).toString();\n}\n\nfunction mkdirpSync(p) {\n  if (fs.existsSync(p)) {\n    return;\n  }\n  mkdirpSync(path.dirname(p));\n  fs.mkdirSync(p);\n}\n\nfunction removeSync(p) {\n  exec(`rm -rf \"${p}\"`);\n}\n\nconst src = path.resolve(path.join(__dirname, \"..\"));\nconst dst = path.resolve(path.join(__dirname, \"..\", \"_release\"));\n\nremoveSync(dst);\nmkdirpSync(dst);\n\nfor (const file of filesToCopy) {\n  const p = path.join(dst, file);\n  mkdirpSync(path.dirname(p));\n  fs.copyFileSync(path.join(src, file), p);\n}\n\nfs.copyFileSync(\n  path.join(src, \"scripts\", \"release-postinstall.js\"),\n  path.join(dst, \"postinstall.js\")\n);\n\nconst filesToTouch = [\n  \"{{ project_slug }}\"\n];\n\nfor (const file of filesToTouch) {\n  const p = path.join(dst, file);\n  mkdirpSync(path.dirname(p));\n  fs.writeFileSync(p, \"\");\n}\n\nconst pkgJson = {\n  name: \"@{{ npm_username }}/{{ project_slug }}\",\n  version: \"%%{% raw %}VERSION{% endraw %}%%\",\n  description: \"{{ project_description }}\",\n  author: \"{{ username }}{% if author_email %} <{{ author_email }}>{% endif %}\",\n  license: \"MIT\",\n  homepage: \"https://github.com/{{ github_username }}/{{ project_slug }}\",\n  bugs: {\n    url: \"https://github.com/{{ github_username }}/{{ project_slug }}/issues\"\n  },\n  repository: {\n    type: \"git\",\n    url: \"https://github.com/{{ github_username }}/{{ project_slug }}.git\"\n  },\n  scripts: {\n    postinstall: \"node postinstall.js\"\n  },\n  bin: {\n    {{ project_slug }}: \"{{ project_slug }}\"\n  },\n  files: [\n    \"platform-windows-x64/\",\n    \"platform-linux-x64/\",\n    \"platform-darwin-x64/\",\n    \"postinstall.js\",\n    \"{{ project_slug }}\"\n  ]\n};\n\nfs.writeFileSync(path.join(dst, \"package.json\"), JSON.stringify(pkgJson, null, 2));\n"

  let d_48d9d90ce5f13f1b7cbddff6cbce0a56 = "open Ppxlib\n\nmodule Builder = Ast_builder.Default\n\nlet expand ~loc ~path:_ (num : int) =\n  let (module Builder) = Ast_builder.make loc in\n  [%expr [%e Builder.eint num] + 5]\n\nlet name = \"{{ project_snake }}\"\n\nlet extension =\n  Extension.declare\n    name\n    Extension.Context.expression\n    (let open Ast_pattern in\n    single_expr_payload (eint __))\n    expand\n\nlet rule = Context_free.Rule.extension extension\n\nlet () = Driver.register_transformation name ~rules:[ rule ]"

  let d_4bd2f36f3eae22d56b7e676cb0a96216 = "{% if test_framework == 'Rely' -%}\nopen Test_framework\n\nlet test_simple_addition { expect; _ } =\n    let result = [%{{ project_snake }} 5] in\n    (expect.int result).toBe 10\n\nlet () =\n    describe \"Simple\" @@ fun { test; _ } ->\n    test \"5 + 5 should equal 10\" (test_simple_addition)\n{%- else -%}\nopen Alcotest\n\nlet test_simple_addition () =\n    let result = [%{{ project_snake }} 5] in\n    check int \"same value\" 10 result\n\nlet suite = [ \"5 + 5 should equal 10\", `Quick, test_simple_addition ]\n{% endif %}"

  let d_663ba856fb35aa1170b7eb61975f00c4 = "{% if test_framework == 'Rely' -%}\n(** Main entry point for our test runner.\n\n    This simply calls the test framework CLI defined by Rely in the test\n    library.\n\n    We separate the test runner binary and the test library so that we can link\n    all the modules in the library when compiling. This allows us to discover\n    all the test automatically, instead of having to manually include them. *)\n\nlet () = {{ project_snake | capitalize }}_test.Test_framework.cli ()\n{%- else -%}\nopen {{ project_snake | capitalize }}_test\n\n(** Main entry point for our test runner.\n\n    This aggregates all the test suites and call Alcotes to run them. When\n    creating a new test suite, don't forget to add it here! *)\n\nlet () =\n  Alcotest.run \"{{ project_slug }}\" [ \"Simple\", Simple_test.suite ]\n{% endif -%}\n"

  let d_71da466b0ad1679de495d5ccc69f3fc0 = "#!/bin/bash\n\nset -e\n\nif [ -d \".git\" ]; then\n  changes=$(git status --porcelain)\n  branch=$(git rev-parse --abbrev-ref HEAD)\n\n  if [ -n \"${changes}\" ]; then\n    echo \"Please commit staged files prior to bumping\"\n    exit 1\n  elif [ \"${branch}\" != \"master\" ]; then\n    echo \"Please run the release script on master\"\n    exit 1\n  else\n    {% if package_manager == 'Esy' %}esy x {% endif %}dune-release tag\n    {% if package_manager == 'Esy' %}esy x {% endif %}dune-release distrib\n    {% if package_manager == 'Esy' %}esy x {% endif %}dune-release publish distrib -y\n    {% if package_manager == 'Esy' %}esy x {% endif %}dune-release opam pkg\n    {% if package_manager == 'Esy' %}esy x {% endif %}dune-release opam submit --no-auto-open -y\n  fi\nelse\n  echo \"This project is not a git repository. Run `git init` first to be able to release.\"\n  exit 1\nfi\n"

  let d_74032ccbc2f0e8e5d43862d0ec2e831f = "{\n  \"name\": \"{{ project_slug }}\",\n  \"esy\": {\n    \"build\": \"dune build -p #{self.name}\",\n    {%- if syntax == 'Reason' %}\n    \"buildDev\": \"refmterr dune build --root . --only-package #{self.name}\",\n    {% else %}\n    \"buildDev\": \"dune build --root . --only-package #{self.name}\",\n    {% endif -%}\n    \"buildEnv\": {\n      \"ODOC_SYNTAX\": \"{% if syntax == 'Reason' %}re{% else %}ml{% endif %}\"\n    }\n  },\n  \"dependencies\": {\n    \"@opam/ppxlib\": \"*\",\n    \"@opam/dune\": \">= 2.0\",\n    {%- if syntax == 'Reason' %}\n    \"@opam/reason\": \"*\",\n    {%- endif %}\n    \"ocaml\": \">= 4.8.1000\"\n  },\n  \"devDependencies\": {\n    {% if test_framework == 'Alcotest' -%}\n    \"@opam/alcotest\": \"*\",\n    {% endif -%}\n    \"@opam/dune-release\": \"*\",\n    \"@opam/merlin\": \"*\",\n    {% if syntax == 'OCaml' -%}\n    \"@opam/ocamlformat\": \"*\",\n    {% endif -%}\n    \"@opam/odoc\": \"*\",\n    \"@opam/utop\": \"*\",\n    {% if test_framework == 'Rely' -%}\n    \"@reason-native/rely\": \"*\",\n    {%- endif -%}\n    {%- if syntax == 'Reason' %}\n    \"refmterr\": \">= 3.3.0\",\n    {%- endif %}\n    \"ocaml\": \"~4.09.0\"\n  },\n  \"scripts\": {\n    \"start\": \"esy x {{ project_slug }}\",\n    \"test\": \"esy {% if test_framework == 'Rely' %}dune exec test/test_runner.exe{% else %}dune build @test/runtest -f{% endif %}\",\n    \"doc\": \"esy dune build @doc\",\n    \"doc-path\": \"esy echo #{self.target_dir}/default/_doc/_html/index.html\",\n    \"format\": \"esy dune build @fmt --auto-promote\",\n    \"watch\": \"esy dune build -p #{self.name} --watch\",\n    \"utop\": \"esy dune utop lib -- -implicit-bindings\",\n    \"release\": \"./script/release.sh\"\n  }\n}"

  let d_75608a2495961c048bb914e395df8d2a = "(** Main module *)\n"

  let d_9155ab28356b46f1b5fce81df83d06fc = "# {{ project_name }}\n\n{% if ci_cd == 'Github' -%}\n[![Actions Status](https://github.com/{{ github_username }}/{{ project_slug }}/workflows/CI/badge.svg)](https://github.com/{{ github_username }}/{{ project_slug }}/actions)\n{%- endif %}\n[![NPM Version](https://badge.fury.io/js/%40{{ npm_username }}%2F{{ project_slug }}.svg)](https://badge.fury.io/js/%40{{ npm_username }}%2F{{ project_slug }})\n\n{%- if project_description %}\n\n{{ project_description }}\n{%- endif %}\n\n## Features\n\n- Deploy prebuilt binaries to be consumed from Bucklescript projects\n\n## Installation\n\n### With `opam` on native projects\n\n```bash\nopam install {{ project_slug }}\n```\n\n### With `esy` on native projects\n\n```bash\nesy add @opam/{{ project_slug }}\n```\n\n### With `npm` on Bucklescript projects\n\nThe recommended way to use PPX libraries in Bucklescript projects is to use `esy`.\n\nCreate an `esy.json` file with the content:\n\n```json\n{\n  \"name\": \"test_bs\",\n  \"version\": \"0.0.0\",\n  \"dependencies\": {\n    \"@opam/{{ project_slug }}\": \"*\",\n    \"ocaml\": \"~4.6.1000\"\n  }\n}\n```\n\nAnd add the PPX in your `bsconfig.json` file:\n\n```json\n{\n  \"ppx-flags\": [\n    \"ppx-flags\": [\"esy x {{ project_slug }}\"]\n  ]\n}\n```\n\nHowever, if using `esy` bothers you, we also provide a NPM package with prebuilt binaries.\n\n```bash\nyarn global add @{{ npm_username }}/{{ project_slug }}\n# Or\nnpm -g install @{{ npm_username }}/{{ project_slug }}\n```\n\nAnd add the PPX in your `bsconfig.json` file:\n\n```json\n{\n  \"ppx-flags\": [\n    \"ppx-flags\": [\"@{{ npm_username }}/{{ project_slug }}\"]\n  ]\n}\n```\n\n## Usage\n\n`{{ project_snake }}` implements a ppx that transforms the `[%{{ project_snake }}]` extension into an expression that adds 5 to the integer passed in parameter.\n\nThe code:\n\n```ocaml\n[%{{ project_snake }} 5]\n```\n\nWill transform to something like:\n\n```ocaml\n5 + 5\n```\n\n## Contributing\n\nTake a look at our [Contributing Guide](CONTRIBUTING.md).\n"

  let d_96d9452584ebc88b25cfa3a5e33963cc = "(library\n (name {{ project_snake }})\n (public_name {{ project_slug }})\n (libraries ppxlib)\n (kind ppx_rewriter)\n (preprocess\n  (pps ppxlib.metaquot ppxlib.runner))\n (flags (:standard -open StdLabels)))\n\n(include_subdirs unqualified)\n"

  let d_c83d5ebe61cd4f1c3fea6b0cd57b6eb2 = "open Ppxlib\n\nlet _ = Driver.run_as_ppx_rewriter ()"

  let d_cd88a73842f700c1d7039c4da48b093c = "(library\n (name {{ project_snake }}_test)\n (libraries {% if test_framework == 'Rely' %}rely.lib{% else %}alcotest{% endif %} {{ project_slug }})\n (modules\n  (:standard \\ test_runner))\n (preprocess\n  (pps {{ project_slug }}))\n (flags (:standard -linkall -g -open StdLabels{% if test_framework == 'Rely' %} -w +A-48-42-40{% endif %})))\n\n(executable\n (name test_runner)\n (libraries {% if test_framework == 'Rely' %}rely.lib{% else %}alcotest{% endif %} {{ project_snake }}_test)\n (modules test_runner)\n (preprocess\n  (pps {{ project_slug }}))\n (flags (:standard -open StdLabels{% if test_framework == 'Rely' %} -w +A-48-42-40{% endif %})))\n\n(rule\n (alias runtest)\n (action\n  (run ./test_runner.exe -q --color=always)))\n\n(include_subdirs unqualified)\n"

  let d_fe5021aa06ff886636bd0737eff56601 = "(inherit (official bin))\n\n(name ppx)\n(description \"PPX library with prebuilt binaries for native and bucklescript\")\n\n(ignore \n  (files test/utils_test.ml))\n"

  let file_chunks = function
    | "README.md" | "/README.md" -> Some [ d_3e9e22e70747fd748b90579a40a678ec; ]
    | "spin" | "/spin" -> Some [ d_fe5021aa06ff886636bd0737eff56601; ]
    | "template/README.md" | "/template/README.md" -> Some [ d_9155ab28356b46f1b5fce81df83d06fc; ]
    | "template/bin/dune" | "/template/bin/dune" -> Some [ d_22a4a727f14480a70c5b0ab38d5c0d99; ]
    | "template/bin/main.ml" | "/template/bin/main.ml" -> Some [ d_c83d5ebe61cd4f1c3fea6b0cd57b6eb2; ]
    | "template/bin/main.mli" | "/template/bin/main.mli" -> Some [ d_75608a2495961c048bb914e395df8d2a; ]
    | "template/dune-project" | "/template/dune-project" -> Some [ d_0a98aa2defed3dc469f91f8ffa5b5d73; ]
    | "template/esy.json" | "/template/esy.json" -> Some [ d_74032ccbc2f0e8e5d43862d0ec2e831f; ]
    | "template/lib/dune" | "/template/lib/dune" -> Some [ d_96d9452584ebc88b25cfa3a5e33963cc; ]
    | "template/lib/{{ project_snake }}.ml" | "/template/lib/{{ project_snake }}.ml" -> Some [ d_48d9d90ce5f13f1b7cbddff6cbce0a56; ]
    | "template/script/release-make-skeleton.js" | "/template/script/release-make-skeleton.js" -> Some [ d_4025396dfb5871ced6b8051264e10553; ]
    | "template/script/release-postinstall.js" | "/template/script/release-postinstall.js" -> Some [ d_02ef1536addcb2e5f1f36b2fcd537fb1; ]
    | "template/script/release.sh" | "/template/script/release.sh" -> Some [ d_71da466b0ad1679de495d5ccc69f3fc0; ]
    | "template/test/dune" | "/template/test/dune" -> Some [ d_cd88a73842f700c1d7039c4da48b093c; ]
    | "template/test/simple_test.ml" | "/template/test/simple_test.ml" -> Some [ d_4bd2f36f3eae22d56b7e676cb0a96216; ]
    | "template/test/support/test_runner.ml" | "/template/test/support/test_runner.ml" -> Some [ d_663ba856fb35aa1170b7eb61975f00c4; ]
    | "template/{{ project_slug }}.opam" | "/template/{{ project_slug }}.opam" -> Some [ d_1bf06103822114388bfcdf983af7c5cc; ]
    | _ -> None

  let file_list = [ "README.md"; "spin"; "template/README.md"; "template/bin/dune"; "template/bin/main.ml"; "template/bin/main.mli"; "template/dune-project"; "template/esy.json"; "template/lib/dune"; "template/lib/{{ project_snake }}.ml"; "template/script/release-make-skeleton.js"; "template/script/release-postinstall.js"; "template/script/release.sh"; "template/test/dune"; "template/test/simple_test.ml"; "template/test/support/test_runner.ml"; "template/{{ project_slug }}.opam"; ]
end

let file_list = Internal.file_list

let read name =
  match Internal.file_chunks name with
  | None -> None
  | Some c -> Some (String.concat "" c)

let hash = function
  | "README.md" | "/README.md" -> Some "3e9e22e70747fd748b90579a40a678ec"
  | "spin" | "/spin" -> Some "fe5021aa06ff886636bd0737eff56601"
  | "template/README.md" | "/template/README.md" -> Some "9155ab28356b46f1b5fce81df83d06fc"
  | "template/bin/dune" | "/template/bin/dune" -> Some "22a4a727f14480a70c5b0ab38d5c0d99"
  | "template/bin/main.ml" | "/template/bin/main.ml" -> Some "c83d5ebe61cd4f1c3fea6b0cd57b6eb2"
  | "template/bin/main.mli" | "/template/bin/main.mli" -> Some "75608a2495961c048bb914e395df8d2a"
  | "template/dune-project" | "/template/dune-project" -> Some "0a98aa2defed3dc469f91f8ffa5b5d73"
  | "template/esy.json" | "/template/esy.json" -> Some "74032ccbc2f0e8e5d43862d0ec2e831f"
  | "template/lib/dune" | "/template/lib/dune" -> Some "96d9452584ebc88b25cfa3a5e33963cc"
  | "template/lib/{{ project_snake }}.ml" | "/template/lib/{{ project_snake }}.ml" -> Some "48d9d90ce5f13f1b7cbddff6cbce0a56"
  | "template/script/release-make-skeleton.js" | "/template/script/release-make-skeleton.js" -> Some "4025396dfb5871ced6b8051264e10553"
  | "template/script/release-postinstall.js" | "/template/script/release-postinstall.js" -> Some "02ef1536addcb2e5f1f36b2fcd537fb1"
  | "template/script/release.sh" | "/template/script/release.sh" -> Some "71da466b0ad1679de495d5ccc69f3fc0"
  | "template/test/dune" | "/template/test/dune" -> Some "cd88a73842f700c1d7039c4da48b093c"
  | "template/test/simple_test.ml" | "/template/test/simple_test.ml" -> Some "4bd2f36f3eae22d56b7e676cb0a96216"
  | "template/test/support/test_runner.ml" | "/template/test/support/test_runner.ml" -> Some "663ba856fb35aa1170b7eb61975f00c4"
  | "template/{{ project_slug }}.opam" | "/template/{{ project_slug }}.opam" -> Some "1bf06103822114388bfcdf983af7c5cc"
  | _ -> None

let size = function
  | "README.md" | "/README.md" -> Some 392
  | "spin" | "/spin" -> Some 156
  | "template/README.md" | "/template/README.md" -> Some 1892
  | "template/bin/dune" | "/template/bin/dune" -> Some 200
  | "template/bin/main.ml" | "/template/bin/main.ml" -> Some 50
  | "template/bin/main.mli" | "/template/bin/main.mli" -> Some 19
  | "template/dune-project" | "/template/dune-project" -> Some 730
  | "template/esy.json" | "/template/esy.json" -> Some 1569
  | "template/lib/dune" | "/template/lib/dune" -> Some 233
  | "template/lib/{{ project_snake }}.ml" | "/template/lib/{{ project_snake }}.ml" -> Some 473
  | "template/script/release-make-skeleton.js" | "/template/script/release-make-skeleton.js" -> Some 1964
  | "template/script/release-postinstall.js" | "/template/script/release-postinstall.js" -> Some 2683
  | "template/script/release.sh" | "/template/script/release.sh" -> Some 850
  | "template/test/dune" | "/template/test/dune" -> Some 747
  | "template/test/simple_test.ml" | "/template/test/simple_test.ml" -> Some 506
  | "template/test/support/test_runner.ml" | "/template/test/support/test_runner.ml" -> Some 801
  | "template/{{ project_slug }}.opam" | "/template/{{ project_slug }}.opam" -> Some 1057
  | _ -> None
OCaml

Innovation. Community. Security.