# Cabal setup

Let us organise our code for this course project. We will be writing a number of Plutus validators and our project can have the same structure as `plutus-scripts`.

### The .cabal file

We start off by creating a new directory and initialising a cabal project.

```bash
mkdir hpm-validators && cd hpm-validators
cabal init
```

This will create a default cabal project structure for us that looks like this:

<pre class="language-bash"><code class="lang-bash"><strong>├── app
</strong>│   └── Main.hs
├── CHANGELOG.md
└── hpm-validators.cabal
</code></pre>

We will place all our source code in the `src/` directory so let's rename the `app` directory to `src`. Inspecting the `hpm-validators.cabal` file shows that the project was initialised as an executable, but we will be building a library of validators so we can change that to a library and specify the `hs-source-dirs` to `src`. The rest of the file we can simply copy from the `plutus-scripts.cabal` template (most notably the `build-depends` section). Our complete `hpm-validators.cabal` file looks like this:

```haskell
cabal-version:      2.4
name:               hpm-validators
version:            0.1.0.0

-- A short (one-line) description of the package.
-- synopsis:

-- A longer description of the package.
-- description:

-- A URL where users can report bugs.
-- bug-reports:

-- The license under which the package is released.
-- license:

-- The package author(s).
-- author:

-- An email address to which users can send suggestions, bug reports, and patches.
-- maintainer:

-- A copyright notice.
-- copyright:
-- category:
extra-source-files: CHANGELOG.md

library
    hs-source-dirs:      src
    exposed-modules:     SimplestSuccess

    build-depends:       aeson
                        , base ^>=4.14.1.0
                        , bytestring
                        , containers
                        , cardano-api
                        , data-default
                        , freer-extras
                        , plutus-contract
                        , plutus-ledger
                        , plutus-ledger-api
                        , plutus-ledger-constraints
                        , plutus-script-utils
                        , plutus-tx-plugin
                        , plutus-tx
                        , text
                        , serialise
  default-language:    Haskell2010
  ghc-options:         -Wall -fobject-code -fno-ignore-interface-pragmas -fno-omit-interface-pragmas -fno-strictness -fno-spec-constr -fno-specialise

```

Our `exposed-modules:` exposes `SimplestSuccess` as that will be the first validator script we write.

{% hint style="info" %}
Note that there is also an interactive option `cabal init -i` that you can try out.
{% endhint %}

### The cabal.project file

We do not need to think too much about the `cabal.project` file. Simply copy the full file from `plutus-scripts/cabal.project` as it contains all the dependencies we need. For reference, the full file looks like this:

```haskell
-- Custom repository for cardano haskell packages
-- See https://github.com/IntersectMBO/cardano-haskell-packages on how to use CHaP in a Haskell project.
repository cardano-haskell-packages
  url: https://chap.intersectmbo.org
  secure: True
  root-keys:
    3e0cce471cf09815f930210f7827266fd09045445d65923e6d0238a6cd15126f
    443abb7fb497a134c343faf52f0b659bd7999bc06b7f63fa76dc99d631f9bea1
    a86a1f6ce86c449c46666bda44268677abf29b5b2d2eb5ec7af903ec2f117a82
    bcec67e8e99cabfa7764d75ad9b158d72bfacf70ca1d0ec8bc6b4406d1bf8413
    c00aae8461a256275598500ea0e187588c35a5d5d7454fb57eac18d9edb86a56
    d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee

packages: hpm-validators.cabal

index-state: 2022-11-14T00:20:02Z

index-state:
  , hackage.haskell.org 2022-11-14T00:20:02Z
  , cardano-haskell-packages 2022-11-17T04:56:26Z

-- We never, ever, want this.
write-ghc-environment-files: never

allow-newer:
  -- cardano-ledger packages need aeson >2, the following packages have a
  -- too restictive upper bounds on aeson, so we relax them here. The hackage
  -- trustees can make a revision to these packages cabal file to solve the
  -- issue permanently.
  , ekg:aeson
  , ekg-json:aeson
  , openapi3:aeson
  , servant:aeson
  , servant-client-core:aeson
  , servant-server:aeson

constraints:
  -- cardano-prelude-0.1.0.0 needs
  , protolude <0.3.1

  -- cardano-ledger-byron-0.1.0.0 needs
  , cardano-binary <1.5.0.1

  -- plutus-core-1.0.0.1 needs
  , cardano-crypto-class >2.0.0.0
  , algebraic-graphs <0.7

  -- cardano-ledger-core-0.1.0.0 needs
  , cardano-crypto-class <2.0.0.1

  -- cardano-crypto-class-2.0.0.0.1 needs
  , cardano-prelude <0.1.0.1

  -- dbvar from cardano-wallet needs
  , io-classes <0.3.0.0

  -- newer typed-protocols need io-classes>=0.3.0.0 which is incompatible with dbvar's constraint above
  , typed-protocols==0.1.0.0

-- DELETE
-- The plugin will typically fail when producing Haddock documentation. However,
-- in this instance you can simply tell it to defer any errors to runtime (which
-- will never happen since you're building documentation).
--
-- So, any package using 'PlutusTx.compile' in the code for which you need to
-- generate haddock documentation should use the following 'haddock-options'.
--package plutus-ledger
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"
--package plutus-script-utils
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"
--package plutus-contract
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"

-- These packages appear in our dependency tree and are very slow to build.
-- Empirically, turning off optimization shaves off ~50% build time.
-- It also mildly improves recompilation avoidance.
-- For dev work we don't care about performance so much, so this is okay.
-- package cardano-ledger-alonzo
--   optimization: False
-- package ouroboros-consensus-shelley
--   optimization: False
-- package ouroboros-consensus-cardano
--   optimization: False
-- package cardano-api
--   optimization: False
-- package cardano-wallet
--   optimization: False
-- package cardano-wallet-core
--   optimization: False
-- package cardano-wallet-cli
--   optimization: False
-- package cardano-wallet-launcher
--   optimization: False
-- package cardano-wallet-core-integration
--   optimization: False

-- Waiting for plutus-apps CHaP to be published
source-repository-package
  type: git
  location: https://github.com/intersectMBO/plutus-apps.git
  tag: 65ddfa5d467ed64f8709d7db9faf96151942da82
  subdir:
    cardano-streaming
    doc
    freer-extras
    marconi
    marconi-mamba
    playground-common
    pab-blockfrost
    plutus-chain-index
    plutus-chain-index-core
    plutus-contract
    plutus-contract-certification
    plutus-example
    plutus-ledger
    plutus-ledger-constraints
    plutus-pab
    plutus-pab-executables
    plutus-script-utils
    plutus-tx-constraints
    plutus-use-cases
    rewindable-index

-- Direct dependency.
source-repository-package
    type: git
    location: https://github.com/intersectMBO/quickcheck-dynamic
    tag: c272906361471d684440f76c297e29ab760f6a1e

-- Should follow cardano-wallet.
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-addresses
    tag: b7273a5d3c21f1a003595ebf1e1f79c28cd72513
    subdir:
      -- cardano-addresses-cli
      command-line
      -- cardano-addresses
      core

-- Direct dependency.
-- Compared to others, cardano-wallet doesn't bump dependencies very often.
-- Making it a good place to start when bumping dependencies.
-- As, for example, bumping the node first highly risks breaking API with the wallet.
-- Unless early bug fixes are required, this is fine as the wallet tracks stable releases of the node.
-- And it is indeed nice for plutus-apps to track stable releases of the node too.
--
-- The current version is dated 2022/08/10
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-wallet
    tag: 18a931648550246695c790578d4a55ee2f10463e
    subdir:
      lib/cli
      lib/core
      lib/core-integration
      lib/dbvar
      lib/launcher
      lib/numeric
      lib/shelley
      lib/strict-non-empty-containers
      lib/test-utils
      lib/text-class

-- This is needed because we rely on an unreleased feature
-- https://github.com/intersectMBO/cardano-ledger/pull/3111
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-ledger
    tag: da3e9ae10cf9ef0b805a046c84745f06643583c2
    subdir:
      eras/alonzo/impl
      eras/alonzo/test-suite
      eras/babbage/impl
      eras/babbage/test-suite
      eras/byron/chain/executable-spec
      eras/byron/crypto
      eras/byron/crypto/test
      eras/byron/ledger/executable-spec
      eras/byron/ledger/impl
      eras/byron/ledger/impl/test
      eras/shelley/impl
      eras/shelley/test-suite
      eras/shelley-ma/impl
      eras/shelley-ma/test-suite
      libs/cardano-ledger-core
      libs/cardano-ledger-pretty
      libs/cardano-protocol-tpraos
      libs/cardano-data
      libs/vector-map
      libs/set-algebra
      libs/small-steps
      libs/small-steps-test
      libs/non-integral
```

The project structure that we will create in this course looks like this:

<pre class="language-bash"><code class="lang-bash">hpm-validators
├── cabal.project 
├── CHANGELOG.md
├── compiled                        # Compiled assets and validators 
├── dist-newstyle
├── hpm-validators.cabal
├── src/                            # Haskell source code
│   ├── DeadlineParam.hs
<strong>│   ├── ExploringScriptContext.hs
</strong>│   ├── GuessingGame.hs
│   ├── Helpers/
│   ├── MintingPolicy.hs
│   ├── SharedWallet.hs
│   ├── SharedWalletParam.hs
│   ├── SimplestSuccess.hs
│   └── StakingValidator.hs
└── testnet/                        # Scripts and files for testing validators
    ├── address/
    ├── build-addresses.sh
    ├── DeadlineParam/
    ├── ExploringScriptContext/
    ├── GuessingGame/
    ├── MintingPolicy/
    ├── SharedWallet/
    ├── SharedWalletParam/
    ├── SimplestSuccess/
    └── StakingValidator/
</code></pre>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://plutus.hpmeducation.com/writing-the-first-plutus-scripts/cabal-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
