-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpackaging.nim
249 lines (223 loc) · 9.01 KB
/
packaging.nim
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
##
## packaging and configuring apps
## ==============================
## bookmark: dunno
##[
## TLDR
- ".nims", ".cfg", ".nimcfg", ".nimble" are valid configuration extensions.
- nimble
- shipped with nim isnt the nimbiest version
- install a nimbier nimble with `nimble install nimble`
- is package-level package manager, i.e. pnpm not apt-get
- parallel tasks are described in asyncPar
- nimscript defined here is strictly for app configuration and nimble support
- check targets/shell.nims for in depth nimscripting and tasks
links
-----
- other
- [configs used by nim](https://github.com/nim-lang/Nim/tree/devel/config)
- [example config with tasks](https://github.com/kaushalmodi/nim_config/blob/master/config.nims)
- [nimble repo](https://github.com/nim-lang/nimble)
- [understanding how nim is built for X may help you do the same](https://nim-lang.org/docs/packaging.html)
- high impact docs
- [nimble pkg reference](https://github.com/nim-lang/nimble#nimble-reference)
- [nims intro](https://nim-lang.org/docs/nims.html)
- [parse config](https://nim-lang.org/docs/parsecfg.html)
- niche
- [base object of a lexer](https://nim-lang.org/docs/lexbase.html)
- source
- abc
TODOs
-----
- verify the different app cfg locations
- for some reason (oops) parseCfg is in shell.nims, it should be in this file
- [this file has example of using @if... @end in a cfg file](https://github.com/nim-lang/Nim/blob/devel/lib/pure/asyncdispatch.nim.cfg)
- the packaging section should show examples of
- creating a package (compiled bin)
- creating a library (dont compile, install source files)
- creating a composite library + package (compiling + installing source files)
## nimble
- nim package manager
nimble packages
---------------
- a directory with a .nimble file and one/more .nim files
- the .nimble filename should match the source codes mainFile.nim
- the .nimble file is executed as nimscript, thus you have full access to nims VM
- a package should generally define atleast a test task on install
- requires git/mercurial depending on where you're fetching remote packages from
- nimble package versions: `nimble install blah bleh@123`
- @123 | @>=0.1.2 | @#gitCommitHash | @#head (or any tag)
- @url
creating nimble packages
------------------------
- by default nimble uses [git repos](https://github.com/nim-lang/packages) as its primary source for packages
- each package contains a .nimble file with install & build directives
- [check nimble api src for all .nimble options](https://github.com/nim-lang/nimble/blob/master/src/nimblepkg/nimscriptapi.nim)
- the .nimble file should (but not required to) have the same name as the package
- its interpreted using nimscript and supports any nim vm compatible features
- e.g. tasks can be used to define nimble package-specific commands
- packages install dirs
- libraries: copied to `$nimbleDir/pkgs2/pkgname-ver-checksum`
- binaries: compile -> copy to library dir > symlink to `$nimbleDir/bin`
.. code-block:: Nim
# package metadata
packageName = "if different from $project"
version = "1.2.3"
author = "rohtua"
description = "6 pack of ramen"
license = "TO KILL"
# package directives
# skipDirs, skipFiles, skipExt <-- deny list: will never be installed
# installDirs, installFiles, installExt <-- allow list: will only be installed
installExt = @["nim"] # required if your pkg is both a library & binary
srcDir = "./src"
bin = @["myMainFile"] # compile this file before installing
skipExt = @["nim"] # dont install source .nim files (we only want to copy the compiled bin)
binDir = "./bin"
backend = "c"
namedBin["main"] = "mymain" # rename binary
namedBin = {"main": "mymain", "main2": "other-main"}.toTable() # rename binaries
# package dependencies
# ^= latest compatible semver
# ~= latest version by increasing the last digit to highest version
requires "nim >= 1.6.10", "sim ^= 10.6.1"
requires "dim ~= 6.1.10"
requires "wim > 0.1 & <= 0.5"
requires "lim#head" # the latest commit
requires "pim == 1.2.3" # not recommended; as transient deps could rely on a diff ver
requires "https://github.com/user/pkg#abcd"
# foreign deps: not managed by nimble, e.g. openssl
when defined(nimdistros):
import distros
if detectOs(Ubuntu):
foreignDep "libssl-dev"
else:
foreignDep "openssl"
# package tasks: list a pkgs tasks via `nimble tasks`
# see task section below
package directives
------------------
- author
- backend
- bin
- binDir
- description
- installDirs
- installExt
- installFiles
- license
- packageName
- skipDirs
- skipExt
- skipFiles
- srcDir
- version
- requires(varargs[string])
package dir structure
---------------------
.. code-block:: Nim
├── LICENSE
├── README.md
├── foobar.nimble # The project .nimble file
├── foobar.nim # only put it here if this is the only module
└── src
├── foobar.nims # cfg specifically for sibling foobar.nim
├── foobar.nim # Imported via `import foobar`
│ └── foobar # package module dir
│ │ ├── utils.nim # Imported via `import foobar/utils`
│ │ ├── common.nim # Imported via `import foobar/common`
└── private # consumers cant import private modules
│ │ │ ├── hidden.nim # internally you can `import foobar/private/hidden`
└── tests # Contains the tests
├── config.nims
├── tfoo1.nim # First test
└── tfoo2.nim # Second test
creating nimble libraries
-------------------------
- all previous info still stands correct, however pay attention to the following
- libraries arent pre-compiled, thus the directory structure most be obeyed
- if the library contains a single module, it can be in the root directory next to the .nimble file
- else create MyPackageName dir and put library files in there
- consumers can then `import myPackageName / myModuleName`
releasing and publishing packages
---------------------------------
- be sure to compile with nimble and NOT nim
- nimble adds extra checks, e.g. package dependencies are listed in the .nimble file
- releasing
- increment the version in .nimble
- commit changes
- tag the commit `git tag v1.2.3`
- this MUST MATCH the version number in step 1, else nimble will refuse to install it
- git push --tags
- publishing
- use `nimble publish`
- or manually clone the [packages](https://github.com/nim-lang/packages) repo and submit a PR
nimble configuration
--------------------
- posix: ~/.config/nimble/nimble.ini
- windows: Users\someuser\AppData\Roaming\nimble\nimble.ini
.. code-block:: Nim
# where to install pkgs
nimbleDir = r"~/nimble/"
# if true will add chcp 65001 to .cmd stubs generated in ~/.nimble/bin/
chcp = true
# specify new custom package list(s)
# over default with one named "Official"
# multiple path/urls can be specified per name
[PackageList]
name = "My local list"
path/url = r"/any/path/or/url"
cloneUsingHttps = true # replace git:// with https://
httpProxy = ""
## nimscript for app configuration
- subset of nim that can be evaluated by nims builtin VM
- see backends/shell.nim for indepth nimscript
- as well as tasks, as they can only be run in `.nims` and `.nimble` files
`.nims` as config files
-----------------------
- nim will automatically process .nims configs in the following order (later overrides previous)
.. code-block:: Nim
# $project === name of the file being compiled
# i.e. compiling blah.nim will automatically load blah.nims
$XDG_CONFIG_HOME/nim/config.nims || ~/config/nim/config.nims
$parentDir/config.nims
$projectDir/config.nims
$project.nims
- syntax for setting switches has 2 forms
.. code-block:: Nim
switch("opt", "size") || hint(name, bool) || warning(name, bool)
--opt:size # IMO the cleaner syntax
## parsecfg
- high performance config parser in windows ini syntax
- fully supported in .nim files
- semi supported in .nims and .nimble files
- supports string literals, raw and triple quoted nim strings
parsecfg types
--------------
- CfgEvent object describing the parsing event
- kind enum CfgEventKind the type of line being parsed
- cfgSectionStart the start of config section
- section returns [name]
- cfgKeyValuePair in the form key=value
- key
- value
- cfgOption in the form --key=value
- key
- value
- cfgError failed to parse
- msg reason
- cfgEof end of file
- CfgParser object BaseLexor
- Config OrderedTableRef
parsecfg procs
--------------
- delSectionKey from in in a specific/empty str section
- getSectionValue from a key in a specific/empty str section
- loadConfig from a path
- newConfig() dictionary
- setSectionKey set key & value in a specific/empty str section
- writeConfig to a path
- close parser and its associated stream
- delSection and all associated keys
- errorStr of error event with line and column
]##