Refactoring and using Git Rebase!
Tags: opensource, github
Published: 2023-10-13 22:56:58

This week, I did not add any new features to my open source project, [go-go-web](https://github.com/kliu57/go-go-web); however, I did do some clean up of my code. **Refactoring** is the process of reorganizing or restructuring code without changing the functionality. When I took a quick look at my code, I found there were many improvements to made, such as getting rid of global variables, reducing the amount of duplicated code, and extracting functions to avoid having long code blocks that may be hard to debug in the future.

Here are the ways I refactored my code:

#### 1. Removed global variable

I used to use a global variable called `DEFAULT_OUTPUT` to store the default output path or folder name which was `./til`. When output is not specified by the user, all outputs will end up in the `til` folder. I did some research online and found that using global variables is considered not best practice by many. Thus, I decided to store the default output location in a file called `_output_dir.py` instead. Since I am now reading from a file, I also had to add error catching for when the file cannot be read or the file is empty.

#### 2. Extracted functions

To avoid having long code blocks which may be hard to debug in the future, I extracted functions to make a code block shorter. In my `main` method, I used to have blocks of code to get the options specified by the user by parsing the config file, or by parsing the command-line arguments typed by the user. 
```
        if args.fname:
            if args.config:
                # code block to get options from 
                # config file and set it to
                # local variables
            else:
                # code block to get options from 
                # command-line and set it to
                # local variables
```
I made two new functions, `parse_config()` and `parse_cmdline()` and was able to take out a lot of code from main, making my code block in `main` shorter and more manageable.
```
        if args.fname:
            if args.config:
                options = parse_config()
            else:
                options = parse_cmdline()
```
#### 3. Got Rid of Duplicating Code

I noticed that I had two functions, `text_to_html()` and `markdown_to_html()` which contained duplicated code. The code that was duplicated was the html that had to written into the page head before the body and the html closing tags after the body. To clean this up so I would not have the same code repeated twice anywhere, I created two new functions: `get_html_before_body()` and `get_html_after_body()`. Now I could simply call these new functions in one line rather than have 6-7 lines of duplicated code.

#### 4. Found a bug

While refactoring my code, I found a small bug: `sys.exit()` was not called after some errors happened, and I fixed it.

---

### Using Git Rebase to Squash Commits

Every time I finished one of the above refactoring issues, I did a `git add` and `git commit` with a specific message. At the end of the process I had multiple commits that I wanted to squash into one. I did this using **Interactive Git Rebase**. This was my first time using Interactive Git Rebase, and at first I was unsure how to proceed when I was presented with a list of my commits. I consulted a [useful guide](https://hackernoon.com/beginners-guide-to-interactive-rebasing-346a3f9c3a6d) I found online and quickly understood that I only needed to use the vim editor to write "pick" or "squash" or "drop" in front of my commits and then do `ESC` `:wq`. I did "pick" on my first commit and "squash" on the rest, and it merged all my commits into one, including the messages!

I then used an Amended Git Commit to reformat my [commit](https://github.com/kliu57/go-go-web/commit/3994512bd19b18e6acf6444a8c637423ddd82596) message to make it look nicer.