Working with remotes
Tags: opensource, toml, git, python
Published: 2023-10-08 07:28:07

This week, had a good practice working with **git remotes** as part of my school's open source course curriculum. We've been working on [TIL](https://dictionary.cambridge.org/dictionary/english/til#:~:text=Meaning%20of%20TIL%20in%20English&text=abbreviation%20for%20today%20I%20learned,Fewer%20examples) post builder tool since the beginning of term, and this week, we had to add another feature to each other's projects.

## The Feature 🗃️

The existing [project](https://github.com/ijacobs-cpa/textml) I opened an issue for already had support for parsing markdown files and custom behavior with various commandline options. However, its really tedious and painful to specify all the options each time you want to run the program. Especially, when the options you are using a fixed set of options on most runs.

### TOML

To counter this problem, we had to add support for another flag `-c` or `--config`, that would allow users to specify a [TOML](https://toml.io/en/) format configuration file.

The file would store user's preferences for certain supported options and those options would be loaded up into the program, overriding any of those options specified directly on the commandline.

## Implementation 👨‍💻

Implementing this feature wasn't particularly hard as there were only 2 major operations that had to be performed:

1. Listen for the `-c`/`--config` to get the path of TOML file
2. Parse the TOML file and load the arguments

And for both of these, I had libraries at my disposal.

For parsing commandline arguments, the maintainer was using a the [argparse](https://docs.python.org/3/library/argparse.html) library, which I am using for [my project](https://github.com/Amnish04/til-page-builder) as well. So, it was as simple as adding this block of code to listen for an additonal option.

```python
parser.add_argument('-c','--config', metavar='config', 
type=str, help="Allows to specify all the options in a TOML formatted configuration file instead of having to pass them all as command line arguments every time.")
```

Parsing the specified `TOML` file with the `-c` flag was delegated to a library called [tomli](https://pypi.org/project/tomli/), which has become a part of python after `v11` under the name of [tobllib](https://docs.python.org/3/library/tomllib.html).
For my case, I installed from `Pypi` as I have python 10 installed on my system.

The following piece of code did all the remaining job from parsing the `TOML` file, and loading the appropriate options.

```python
if args.config is not None:
    args = read_config_file(args, args.config)

def read_config_file(original_args, file_path):
    """Parses the toml configuration file, returns the parsed options as a dictionary"""

    # Start with default arguments
    args = original_args

    # Read the TOML file
    try:
        with open(file_path, "rb") as file:
                custom_configuration = tomli.load(file)
    except tomli.TOMLDecodeError:
        sys.exit("Supplied TOML file is not valid.")
    except:
        sys.exit("File path supplied to --config or -c option is invalid.")

    # Set the specified options, use default if any not specified 
    for (key, value) in custom_configuration.items():
        setattr(args, key, value)

    return args
```

And that was all for the coding part. Seems kinda crazy how it is possible to such a complex feature with just a few lines of code. All thanks to the overpowered python libraries developed by smart people like you out there 😉.

## Working with remotes 📱

Its time to talk about the main topic of the blog, i.e., **git remote**. A git remote, in laymen terms, is a reference to a remote repository (not on local machine) hosted on a platform like github. This reference can be used to perform various operations with that repository like `push`, `pull`, or `fetch`.

### The Workflow 🚬

Before starting to code the feature, I forked the owner's repository, also called the upstread repository for my [fork](https://github.com/Amnish04/textml). Following that, I cloned my fork from github to my local machine.

```
git clone https://github.com/Amnish04/textml.git
```

I coded the feature after checking out on a local topic branch [issue-12](https://github.com/Amnish04/textml/tree/issue-12), which referred to the [issue](https://github.com/ijacobs-cpa/textml/issues/12) I had opened on the upstream repository. After I was done, I pushed all the changes to the `issue-12` branch of my `origin` remote.

```
git push origin issue-12
```

in this case publishing my `issue-12` branch to the remote as I had created it on my local repo.

### Pull Request

Once the changes were in my `origin` repo, I created a [pull request](https://github.com/ijacobs-cpa/textml/pull/13) from origin's `issue-12` branch to upstream repo's `main` branch.

The owner didn't have any problems with my changes and happily merged the PR. This added all the changes to upstream's main branch.

### Pulling from `Main` 🧲

The final step of the workflow was to pull all the latest changes to upstream's `main` branch to my origin's `main` branch, which was at this point a number of commits behind the former.

To do this, all I had to do was

```git
git pull upstream main
```

or alternatively

```git
git fetch upstream
git merge upstream/main
```

In the second option, first command downloads everything from the upstream repo to the local repo but does not merge. And the second command merges the remote branch manually into the current, i.e., `local main` branch.

Sounds complicated, but trust me it isn't once you get the hang of it.

Now that I had my local main branch up to date with upstream's main branch, it was time to line up all the `3 mains`. To do this, I pushed all the recent changes from local main branch to origin's main branch likes so:

```
git push origin main
```

And voila, there you have it. All main together.

![All mains together](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/etdm29pumkn3ro0gwkny.png)

## Conclusion 🔚

Even though I had a general idea about how remotes in git work, performing this workflow helped further solidify my knowledge and concepts.

So why don't we end this blog with a rhyme.

> If you got changes to promote, better grap that git remote.

Sorry about that!