Learning Nim: Adding A Package to Nim Ecosystem
Tags: nim, tutorial
Published: 2020-02-28 17:59:54

I recently published my [first package](https://github.com/nim-lang/packages/pull/1376) in the Nim ecosystem. In this post I am going to show how I did it. 

The package I published is called [luhny](https://github.com/sigmapie8/luhny) it is the Luhn's Algorithm's implementation in Nim. Using this, you can validate any credit card number as Luhn's Algorithm is the standard for credit card validation.

#### But why would I make a package out of it?
I created it for two reasons:
* I wanted to know how to publish a package
* I want to add a generate valid numbers functionality that people may be able to use in the future.

### **Step 1: Make a Repository**
No matter how small or how easy of a thing you're building. Good habits help you go a long way. 
```
git init <name of your package>
```

### **Step 2: Repository Structure**
You're free to choose whatever structure you want. I saw a couple of packages on github and decided to go with the following structure:
```
luhny
|_____________ .git
|_____________ .gitignore
|_____________ luhny
               |________ luhny.nim
|_____________ tests
               |________ test.nim
               |________ config.nims #notice the extra 's'
|_____________ readme.md
|_____________ luhny.nimble
```
You can know about the updated package structure [here](https://github.com/nim-lang/nimble#project-structure)

### **Step 4: Tests**
Again, habits matter. No matter how small or easy your code is, you got to test it. I tried to use nim's `unittest` module.
```nim
#test.nim
# Blueprint for a basic test suite

import unittest
import luhny # code that I want to test

#A test may or may not contain more than one test
suite "<name of your test suite>":
    echo "Initializing"
    
    # use it if you want to run any code before every test
    setup:
        echo "setup code executed"
        
    # use it if you want to run any code after every test
    teardown:
        echo "teardown code executed"
    
    #test1
    test "<name of your test that your want to display>":
        check(<function you want to test>() == <its expected outcome>)
        
    #for example
    test "Wrong input test":
        check(check_number("12345") == false)
        
    test "Correct input test":
        check(check_number("4532196437678779") == true)
        
    test "Single 0":
        check(check_number("0") == true)
        
    test "Empty String":
        check(check_number("") == true)
        
    # Message indicating end of tests
    echo "Tests Completed"
```

#### But how does test.nim find luhny.nim? They are in different folders.
Yes, for that we use [nimscript](https://nim-lang.org/docs/nims.html). Remember the `config.nims` file? We'll use that to switch the path.

```nim
#config.nims
switch("path", "$projectDir/../luhny") 
# changed the path of the current directory from tests to luhny.
```
... and that's how tests found luhny. Although, there's another [(official) way to do it](https://github.com/nim-lang/nimble#tests).

After running your tests and getting a satisfactory output, we can work towards making it an actual package by adding a `.nimble` file.

### **Step 5: Add a `.nimble` File**
Go to your project directory, that is, the top directory that has readme file. There you execute the following command:
```
nimble init
```
It will be followed by a series of questions like
* What's the package version
* what's the author name
* what's license and dependencies etc

After filling the details, you can even try to install the package by using `nimble install` inside the project directory.

### **Step 6: Uploading to github**
Remember that till now, everything is going on in your local repository. Now it's time to push the changes to github so that we can share our package with the world.
```
git remote add origin git@github.com:<your-user-name>/<you package name>.git
git push -u origin master
```

### **Step 7: Telling Nimble About Your Package**
There's a separate package repository of Nim packages hosted on [github](https://github.com/nim-lang/packages#readme) that covers this step and is fairly comprehensive about it.

Create a PR and your package would be added to the Nim's Ecosystem when the PR is accepted.

If you learnt anything from this post, please hit ❤️ and share it with other people!