This week in my open source program I spent time refactoring my code in my textml program located on my GitHub here https://github.com/ijacobs-cpa/textml. In addition, I also experimented with git rebase to edit commits made on a refactoring branch.
Refactoring Process
Before beginning to refactor my code for this week I had to find where best to focus on refactoring as I had already refactored some code on my own time.
I mainly focused on refactoring my main file textml.py
and improving my modules as the main function had barely been updated since the first version of the program and could be reduced. The file with the main function was also updated recently with a lot of command-line processing which could be concentrated elsewhere. I also focused here as I had refactored the convertUtils module on my own time, so I wanted to focus elsewhere.
To refactor this section of code I first wanted to separate code that dealt with processing the command line into its own module. I had already removed the converting functions into their own module so to organize this I decided to store all future modules in their own bin/
directory except for the main textml.py
program which would remain at the root of the project.
With this, I moved any argparse usage and TOML file processing into its own module and then referenced the module from the main to get the command line arguments. This effectively split the file into two.
Next, I began looking at how I stored these command line args as variables in my main program and I decided to move them to a class object effectively extracting a class from the code. This helps when these variables need to be passed to a function as I can just pass the entire class allowing for easier maintainability and expansion in the future:
from bin.cli import args as ARGS
class ConvertProperties: # Properties for converted file
def __init__(this, userInput, outDir, lang):
this.userInput = userInput
this.outDir = outDir
this.lang = lang
props = ConvertProperties( # Instanced class of properties
ARGS.input,
ARGS.output,
ARGS.lang
)
With this implemented I then went to work on extracting a function out of the code in my main where it would run the convert functions. This was repeated for directories or files and could be simplified into a single function effectively extracting a function from reused code.
This was completed by providing the class object of converting properties with a file name into a function like below:
def process_file(file, fileProps): # Function to process file in proper file type
ext = os.path.splitext(file)[1]
if ext == ".txt": # Checking if each file's type is supported before converting
utils.convertText(file, props.outDir, props.lang) # Text Conversion
elif ext == ".md":
utils.convertMD(file, fileProps.outDir, fileProps.lang) # Markdown conversion
elif not os.path.isdir(file): # Prints error if file is not supported
raise Exception("Error!: Invalid file type for: " + file + " (Expected .txt, .md)")
Lastly, I updated some variable names in my program to make them more descriptive.
Git rebase
For this refactoring, I created a separate refactoring branch and committed each step separately. I wanted to group these commits into one single commit with descriptions of all the changes.
This was done using git rebase allowing me to squash all commits into one picked one like the demonstration below:
git rebase main -i
In a text editor:
pick 4710009 Commit message 1
squash 0c01069 Commit message 2
squash fd8e932 Commit message 3
squash f9d85bf Commit message 4
squash bfac3d3 Commit message 5
This then converted all my individual commits into one commit with all commit info. I then amended the commit message to indicate that this singular commit was all refactoring.
Its information and all code changes mentioned can be viewed Here
Top comments (0)