Releases: davidkuda/python_pw_cli
Release v0.4: Avoid Pass-Through Design
After reading chapter 7 Different Layer, Different Abstraction in "A Philosophy of Software Design"[0] I decided to change the design of the application. The chapter claims that "Pass-Through Methods" are red flags. Pass-through methods don't add functionality, as the name indicates, they take arguments and pass them through to other methods, without changing the parameters.
I thought that the former design would be great because I could separate the module into two layers: Database (ji.e. json) i/o and the command-line functionalities. I handled most of the functionality in the database layer while the command-line layer didn't add much but passed the args to the database layer.
Now the database layer is only responsible for getting the data, without processing the data. The processing is done directly from the cli-layer. That way the cli-layer becomes really meaningful by contributing functionality.
John Ousterhout also advises using general-purpose methods over specialized methods. The database-layer is now very general-purpose, its main function is to provide access to data, but not manipulate data.
[0]Ousterhout, John. A Philosophy of Software Design, 2nd Edition (p. 51). Yaknyam Press. Kindle Edition.
release v0.3: Use classes and separate source files into folders
Clean Design
In the previous version I did not use classes. The design is now much clearer:
pw_command.py
-> Execute this script from the command line; The control flow is now way easier to read; Instead of calling functions the script calls methods from the new class PasswordCommand
;
pw/pw_json_client.py
-> Serves as the "backend" that handles all reads and writes to the json file that holds the data
crypto/pw_encryption.py
-> Handles everything related to encryption
The main function used to mix different classes. The classes were coupled. Now they are loose and independent.
Clean Code
In the past few months I have studied Clean Code and this release reflects what I have learned so far. For example: The main()
function is at the top of the script and is executed at the bottom of the script. Functionality is extracted into separate functions. Each function is one layer of abstraction. The order of the functions follow the order of the calls in main()
.
release 0.2: Decouple Crypto, change cli args, return objects (not strings)
Version 0.2 is the result of refactoring version 0.1
In version 0.1 "crypto" (encryption / decryption) was implemented inside the file pw_client.py
. In v0.2 it's implemented in the pw command (pw_command.py
). This means that crypto is now decoupled from the client. I have learned that decoupling dependencies is a good architecture practice, hence the refactoring.
I have made an important change to the naming convention. Instead of storing passwords, I am now storing secrets (or secrets data, respectively).
I changed many of the arguments that the cli accepts. Now you can for example use the following new commands:
# Add new secrets data for the entity "decoupling_crypto"
# with the username "DataDave", the website "https://kuda.ai"
# and few additional keyword arguments.
pw -n decoupling_crypto \
-u DataDave \
-w "https://kuda.ai" \
--kwargs brand=fender,guitar=stratocaster,string_gauge=0.10 \
-ow
# See what keys are avaiailable for decoupling_crypto
pw -ks decoupling_crypto
> There are 6 available keys for decoupling_crypto:
> password, username, website, brand, guitar, string_gauge
# Get the key "guitar" from the entity "decoupling_crypto"
# (I know, silly example, but my guitar is standing right next to me :) ):
pw -k guitar decoupling_crypto
> stratocaster
# Generate a random string with 20 characters
# (Why is PayPal not allowing more than 20 characters for their password?!)
pw -r -rl 20
> The random password has been copied into your clipboard.
Initial Work
I am actively using my password manager every day. I am tagging this release because I have just refactored many things. Please refer to the next release notes to see the changes.