Git and Gitlab - Beginners, working as an organized team⚓
In the previous session, you have seen the need for the structuration of a project. This includes organizing its code base and its development workflow, all to at least ease the development by removing or limiting the occurence of conflicts.
Lessons from last session⚓
What went wrong⚓
Whenever a feature was added to the application, merge conflicts occured. It's possible to work this way, but very inefficient, and it grows worst as the project grows (the size of its code base) and the number of contributors grows.
Causes⚓
There are mainly two causes to this inefficiency, and they are both organizational in nature:
- Code badly structured: a monolithic code, contained in a single file, unmodular
- Bad team workflow: everybody working on the same branch, constantly rewriting each other
A badly structured code multiplies the risks for merge conflicts, as a simple feature addition or bug correction can span multiple line edits across the code base. Some lines need always to be edited when others are edited as well (coupling). This latter problem can even cause other development (and maintenance) problems down the road.
A wrong choice of team development workflow could also increase the difficulty, and make development less efficient. In this case, it is less a matter of a workflow that is bad in the absolute, but the workflow should be adapted to the size of the project, the team and its experience. In this case, as you were working both on the same branch, and on the same file, you had the worst possible combination.
Note
Eeverybody working on the same branch could be perfectly valid, though it should be reserved for very simple projects of small teams of experienced developers.
Possible Solutions⚓
As the code structure was a big reason for the problems you encountered, a solution would be to refactor the code, restructuring it so the different functionalities are cleanly and clearly separated (modularity). Also the functionalities inside one file should be also modular, organized inside functions that should be as small as possible and focus on a single task or functionality (separation of concerns). This way, a new feature could be as simple as writing a new single python function in the appropriate file, and a bug correction or patch as simple as editing a single existing function.
Now to avoid having a conflict on every push on the Gitlab repository, you could
develop on different temporary branches (focusing on one task at a time), keeping the main branch to gather only the fully developed
features, and start development from, ensuring it's always clean, functional and the most uptodate.
You should also pull often from the main branch, to be sure you are uptodate on your local machine.
Even better, we could sanctify the main branch, making its special status formal by
protecting it (i.e disabling some git operations, making them only possible through Gitlab).
Then every direct push operations on the main branch would be forbidden, using Gitlab Merge Requests to process merges on main though Gitlab UI.
Note
This workflow is often referred to as Github Flow.
It has the advantage to be widely used, flexible and relatively simple and is thus used a lot on Github and more largely for open source projects.
Collaborate cleanly as a team⚓
Starter Code⚓
To make it easier, we are already providing you with a better written refactored version of the smart todo list application code.
main.py
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 | |
storage.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
commands.py
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 | |
Instructions⚓
- One group member replace the one
main.pyfile with the new 3 python files. This can be done on themainbranch. Don't forget to push! -
One group member protects the
mainbranch on Gitlab (allowing Maintainers to merge, allowing no one to push and merge, forbidding force push) -
Every group member can now pull the
mainbranch - Every group member can test the new code:
python main.py - Split the list of tasks between each other
-
For every task, follow this simple workflow
- Go on the
mainbranch - Update your
mainbranch by pulling from the Gitlab repository -
Create the temporary branch for the task
Tip
As a good practice, you should name your temporary branch to reference what it is supposed to implement (the task). For this formation, it could be as simple as naming it
feature/TASK_IDwithTASK_IDthe task number (ex:feature/7) -
Go on that temporary branch (reminder: Change branch)
- Implement the task
- Push your changes (reminder: add - commit - push)
-
Open a Merge Request on Gitlab for your branch (See Merge requests). You can tick the box to delete the branch after merge is completed so Gitlab will automatically remove your temporary branch after it's merged, keeping the online repository clean.
Tip
The source branch is the branch you worked on and pushed, the target branch is the branch on which to merge it (
mainin this case) -
Validate and apply the opened Merge Request (they are all listed in the Merge Requests menu)
- Go on the
Development Tasks⚓
To continue developing the smart todo list application, the following set of tasks will need to be completed.
Task 7 – Add a search Command⚓
Add a new command called search that lets the user search for a word inside todos. Matching todos should be printed.
Example:
1 2 3 | |
Tip
This logic belongs in commands.py
Add a new function: search_todos(todos)
Use input(), in, .lower()
Update main.py to recognize the new command
Import the new function
Task 8 – Add Statistics Display⚓
Add a stats command that displays:
- Total number of todos
- Number of completed todos
- Number of incomplete todos
Example:
1 2 3 4 | |
Tip
This logic belongs in commands.py
Add a new function: print_stats(todos)
Completed todos start with [x]
Use startswith(), for loops, counters
Task 9 – Add Tags to Todos⚓
Add a new command called tag that lets users add a tag (e.g. #school, #work) to a todo.
Example:
1 2 3 | |
Todo becomes: [ ] Do homework | priority=low | due=none | #school
Tip
This logic belongs in commands.py
Add a new function: add_tag(todos)
You can append " | #tagname" to the todo string
Use string concatenation
Be careful not to erase existing data
Task 10 – Export Todos to a Report File⚓
Add a command called export that saves all todos to a file named report.txt.
Each todo should be on its own line.
Tip
This is file logic → put it in storage.py
Use open(filename, "w"), .write()
Then call this function from main.py
Task 11 – Add a help Command⚓
Add a help command that prints all available commands and what they do.
Example:
1 2 3 4 5 6 7 8 | |
Tip
This is a simple command → put it in commands.py
Use simple print() statements
No complex logic needed
You might want to take some advance and include the commands added by the other tasks in this session.
Note
There are better ways to maintain a list of commands for an app and have
a help command that always include all commands while not needing to be itself modified.
It is a python software architecture concern, out of the scope of this formation.
Task 12 – Add Undo (Single-Level)⚓
Add a command undo that restores the previous state of the todo list.
Only one level of undo is required.
Tip
You need to save a copy of the list before each change
Use list.copy()
Store the old version in a variable like previous_todos
Restore it when undo is called
Documentation⚓
Warning
An undocumented project is an unusable project!
Gitlab offers several possibilities to document its projects, from a simple readme file in minimalist text format to a custom website. A README.md file in Markdown format at the root of the project will be displayed directly in Gitlab automatically.
- Markdown syntax: https://docs.framasoft.org/en/grav/markdown.html
- Gitlab specifics: https://docs.gitlab.com/ee/user/markdown.html
To go further⚓
- Gitlab Issues: guide on how to describe & track work to be done on Gitlab using issues
- Collaborative Git Workflows: a guide detailing how to collaborate on a git project
- Markdown: guides on Markdown (and mkdocs) for building a documentation
- Python Professional Software Development: a serie of guides to explain the fundamentals of python software development