Skip to content

Commit

Permalink
Merge pull request #49 from SenlisO/dev
Browse files Browse the repository at this point in the history
Update development documentation
  • Loading branch information
Batcastle authored Oct 31, 2021
2 parents e4be2d1 + 2dfd870 commit 0d60d7f
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 124 deletions.
63 changes: 61 additions & 2 deletions development.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Development Setup and Tools
# Development environment setup

The following packages are required in order to do development for `system-installer`. Most of these packages are available in most distributions of Linux and many come pre-installed in some distros.

Expand All @@ -19,8 +19,67 @@ The following are not required but may help out
sudo apt install -y python3 gir1.2-gtk-3.0 p7zip-full python3-parted python3-gnupg arch-install-scripts coreutils squashfs-tools pylint
```

You can find a number of tests to make sure your programs work correctly in the `tests` directory. These are currently tailored to how these programs are written, i.e. they work Python scripts. None of the UI is tested yet. Feel free to write more tests and request their addition in a pull request.
# How to get started

Do you know some programming and want to help out, but haven't worked on someone else's codebase before? This section is here for you. These are some recommended steps on how to contribute without diving into specifics.

1. Create a Github account (if necessary)
* It is strongly recommended to protect your github account with 2FA to protect us from your account being compromized.
* SMS 2FA is not recommended
2. Download and install a git management tool.
* [Gitkraken](https://www.gitkraken.com) is recommended
* The rest of the guide assumes you are using Gitkraken.
3. Go to preferences==>SSH. Generate a new private/public key.
4. Go to Github SSH settings and add your public key.
5. Open the Drauger OS Development repository you want to work on.
6. Click the fork button
7. Go to your repositories, you should now see your forked repository of the Drauger OS repository
8. Click on code ==> SSH and copy the URL provided
9. Go into Gitkraken and clone your forked repository using the SSH URL
10. When viewing your repository in Gitkraken, find the dev branch (remote) and have Gitkraken checkout. You should be checked out to the current dev branch of your repository
* While you are working, changes might be made to the Drauger OS repository you forked.
* If changes affect the files you are working on, you may need to rebase from your repository's page. Be aware that your work may be lost, so backup your working files.
* If you rebase, don't forget to pull from gitkraken.
11. Make the desired changes and commits.
12. Push your commits to your repository as necessary
13. When you are finished making your changes, run through the pre-pull checklist
14. Go to the pull requests section of the Drauger OS repository and generate a pull request
* Even if you have permissions to do so, don't approve pull requests you yourself generate

# Pre-pull checklist
- [ ] Run pylint
- [ ] Run unit tests
- [ ] Check type hinting
- [ ] Test the code (run the application)

# Pylint instructions
_more coming soon_

All Python code should conform to `PEP8` as closely as possible. If you open a pull request `pep8speaks` will provide feedback on your `PEP8` conformance.

A good rule of thumb is if your Python code gets a score of `7.5` or higher from `pylint`, and works correctly, the chances of having your pull request accepted is fairly high, but no pull request is guaranteed to be accepted.

# Unit test instructions
_more coming soon_

You can find a number of tests to make sure your programs work correctly in the `tests` directory. These are currently tailored to how these programs are written, i.e. they work Python scripts. None of the UI is tested yet. Feel free to write more tests and request their addition in a pull request.

If, after modifying a function, the unit test fails, fix the issue in the function. Don't modify the unit test unless the functions interface has changed

# Type hinting instructions
_coming soon_

# Recommended coding practices
This section provides standards agreed upon by senior developers. By following these guidelines, you reduce the likelihood the pull request will be returned.

* Your code should be self documenting (i.e. variable names, function names, etc.)
* Comment where necessary. Assume someone else is going to read your code
* Docstrings will describe how others will interface with your function
* other users should not need to read the code in your function to know how to use it
* Harden your function inputs
* Functions should have high functional cohesion -- doing one thing, and doing it well
* Functions should have loose coupling -- limited connections to other functions and high portability
* Minimize the scopes of variables
* Avoid duplicate code
* When able, prioritize code readability

183 changes: 61 additions & 122 deletions usr/share/system-installer/UI/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@
import json
import os
import common
from subprocess import Popen, check_output, DEVNULL
import subprocess
import gi
import auto_partitioner

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk
import auto_partitioner





def has_special_character(input_string):
"""Check for special characters"""
Expand Down Expand Up @@ -545,7 +551,7 @@ def auto_partition(self, button):
self.data["AUTO_PART"] = True

# Get a list of disks and their capacity
self.devices = json.loads(check_output(["lsblk", "-n", "-i", "--json",
self.devices = json.loads(subprocess.check_output(["lsblk", "-n", "-i", "--json",
"-o", "NAME,SIZE,TYPE"]).decode())
self.devices = self.devices["blockdevices"]
dev = []
Expand Down Expand Up @@ -901,8 +907,8 @@ def make_space_parts(self, widget):
for each1 in each["children"]:
self.parts.append(each1["name"],
"%s, filesystem: %s, size: %sGB" % (each1["name"],
each1["fstype"],
int(auto_partitioner.bytes_to_gb(each1["size"]))))
each1["fstype"],
int(auto_partitioner.bytes_to_gb(each1["size"]))))
self.show_all()

def confirm_remove_part(self, widget):
Expand Down Expand Up @@ -1051,18 +1057,39 @@ def confirm_auto_part(self, button):
self.main_menu("clicked")


def input_part(self, button):
"""Manual Partitioning Input Window"""
self.clear_window()
def set_up_partitioner_label(self, additional_message = ""):
"""prepare top label for display on manual partitioner
Keyword arguments:
additonal message -- any errors that need to be displayed below original message
Return value:
label -- the top label ready for additional formatting and display
"""
label = Gtk.Label()
label.set_markup("""

input_string = """
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
""")
"""

if additional_message != "":
input_string = input_string + "\n " + additional_message

label.set_markup(input_string)

label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)

return label


def input_part(self, button):
"""Manual Partitioning Input Window"""
self.clear_window()

label = self.set_up_partitioner_label()
self.grid.attach(label, 1, 1, 3, 1)

label2 = Gtk.Label()
Expand Down Expand Up @@ -1142,16 +1169,7 @@ def onnext4clicked(self, button):
"""Check device paths provided for manual partitioner"""
if ((self.root.get_text() == "") or (
self.root.get_text()[0:5] != "/dev/")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
/ NOT SET
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: / NOT SET")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1161,16 +1179,7 @@ def onnext4clicked(self, button):
self.show_all()
return
elif not os.path.exists(self.root.get_text()):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
Not a Valid Device on /
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: Not a Valid Device on /")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1181,17 +1190,8 @@ def onnext4clicked(self, button):
return
elif (((self.efi.get_text() == "") or (
self.efi.get_text()[0:5] != "/dev/")) and os.path.isdir("/sys/firmware/efi")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
You are using EFI, therefore an EFI partition
must be set.
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label(
"ERROR: System is running EFI. An EFI partition must be set.")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1200,17 +1200,10 @@ def onnext4clicked(self, button):

self.show_all()
return
elif (not os.path.exists(self.efi.get_text()) or (self.efi.get_text() == "")) and os.path.isdir("/sys/firmware/efi"):
elif (not os.path.exists(self.efi.get_text()) or (
self.efi.get_text() == "")) and os.path.isdir("/sys/firmware/efi"):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
Not a Valid Device on /boot/efi
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: Not a Valid Device on /boot/efi")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1223,15 +1216,7 @@ def onnext4clicked(self, button):
self.home.get_text()[0:5] != "/dev/") and (
self.home.get_text() != "NULL")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
Please input a valid device path for HOME partition.
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: invalid HOME partition device path")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1243,16 +1228,7 @@ def onnext4clicked(self, button):
elif (not os.path.exists(self.home.get_text()) and (
self.home.get_text() != "") and (
self.home.get_text() != "NULL")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
Not a Valid Device on /home
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: Not a Valid Device on /home")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1264,17 +1240,8 @@ def onnext4clicked(self, button):
elif ((self.swap.get_text() != "") and (
self.swap.get_text()[0:5] != "/dev/") and (
self.swap.get_text().upper() != "FILE")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
SWAP must be set to a valid partition path, "FILE", or
left empty.
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label(
"ERROR: SWAP must be set to a valid path, 'FILE', or empty.")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1285,16 +1252,7 @@ def onnext4clicked(self, button):
elif (not os.path.exists(self.swap.get_text()) and (
self.swap.get_text().upper() != "FILE") and (
self.swap.get_text() != "")):
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
Not a Valid Device on SWAP
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label("ERROR: Not a Valid Device on SWAP")
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1304,18 +1262,13 @@ def onnext4clicked(self, button):
self.show_all()
return
if ((self.swap.get_text().upper() == "FILE") or (self.swap.get_text() == "")):
if auto_partitioner.size_of_part(self.root.get_text()) < auto_partitioner.get_min_root_size(bytes=False):
label = Gtk.Label()
label.set_markup(f"""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
/ is too small. Minimum Root Partition size is { round(auto_partitioner.get_min_root_size(bytes=False)) } GB
if auto_partitioner.size_of_part(self.root.get_text()) < \
auto_partitioner.get_min_root_size(bytes=False):
label_string = \
f""" / is too small. Minimum Root Partition size is { round(auto_partitioner.get_min_root_size(bytes=False)) } GB
Make a swap partition to reduce this minimum to { round(auto_partitioner.get_min_root_size(swap=False, bytes=False)) } GB
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
"""
label = self.set_up_partitioner_label(label_string)
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1325,17 +1278,10 @@ def onnext4clicked(self, button):
self.show_all()
return
else:
if auto_partitioner.size_of_part(self.root.get_text()) < auto_partitioner.get_min_root_size(swap=False, bytes=False):
label = Gtk.Label()
label.set_markup(f"""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
/ is too small. Minimum Root Partition size is { round(auto_partitioner.get_min_root_size(swap=False, bytes=False)) } GB
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
if auto_partitioner.size_of_part(self.root.get_text()) < \
auto_partitioner.get_min_root_size(swap=False, bytes=False):
label_string = f"/ is too small. Minimum Root Partition size is { round(auto_partitioner.get_min_root_size(swap=False, bytes=False)) } GB"
label = self.set_up_partitioner_label(label_string)
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand All @@ -1344,14 +1290,7 @@ def onnext4clicked(self, button):

self.show_all()
return
label = Gtk.Label()
label.set_markup("""
What are the mount points for the partitions you wish to be used?
Leave empty the partitions you don't want.
<b> / MUST BE USED </b>
""")
label.set_justify(Gtk.Justification.LEFT)
label = self._set_default_margins(label)
label = self.set_up_partitioner_label()
try:
self.grid.remove(self.grid.get_child_at(1, 1))
except TypeError:
Expand Down Expand Up @@ -1379,7 +1318,7 @@ def onnext4clicked(self, button):

def opengparted(self, button):
"""Open GParted"""
Popen("gparted", stdout=DEVNULL, stderr=DEVNULL)
subprocess.Popen("gparted", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
self.data["AUTO_PART"] = False
self.input_part("clicked")

Expand Down

0 comments on commit 0d60d7f

Please sign in to comment.