Developers Toolbox
As developers, we are simply writing codes to solve problems. However, there are common problems while writing code and these common problems are solved by many tools. Using these tools will increase your productivity dramatically. The purpose of this chapter is to introduce common problems that we face while writing code and the some advised tools that are used to solve these problems.
Code Editors and Integrated Development Environments (IDEs)
You can simply write your code by just using a terminal and a text editor. However, reading code from a NotePad and writing code in a NotePad will be very hard although it is completely possible. For this reason, using a code editor or more advanced Integrated Development Environment (IDE) is advised. These tools will help you to write your code faster and more efficiently. I will not define the difference between a code editor and an IDE because the line between them is blurred. Instead I will use the term code editor to refer both of them.
Loosely speaking, a code editor is a text editor that is optimized for writing and editing code. A code editor may have;
- Syntax highlighting to read code easily
- Code folding to hide unnecessary parts of the code
- Auto-completion to write code faster
- Multiple cursors to edit multiple parts of the code at the same time
- Find and replace to search and replace parts of the code
- Code navigation to jump to definitions, find references, etc.
- Code refactoring to change the structure of the code
- Code debugging to find and fix bugs
- Showing errors and warnings to improve code quality
- Running cli commands to use the terminal inside the editor
- Integration with a version control system to manage the code history
There are different kinds of code editors. Some of them are implemented to be used in the terminal like vim
and
emacs
. Some of them are implemented to be used from a graphical user interface like Visual Studio
, IntelliJ IDEA
,
Eclipse
, XCode
, NetBeans
, PyCharm
, WebStorm
, Sublime Text
, Visual Studio Code
etc. It is up to you to
choose the code editor that you like. However, I advise you to pick a code editor that will be used by high majority of
the developers in your team. Because trying to work with very different code editors in a single team will increase the
friction.
Another good practice is to store your code editor settings in version control. This will help you to keep your settings
consistent across different machines. Also, this will help you to share your settings with your team. For instance, if
you are using vscode
, you can put your settings in .vscode/settings.json
file and tasks in .vscode/tasks.json
file.
Also, developers generally extend functionality of their code editors by using plugins. Sometimes these plugins provide crucial functionalities that are not provided by the code editor itself. For instance, you may use a code formatting tool that works from the command line but you may want to integrate it with your code editor to format your code when a file is saved. In these cases, you will find these plugins very useful and you will want to share these plugins with your team. Again, I believe that storing these plugins in version control is a good practice to align your team.
My last advise is to pick a lightweight code editor that is actively developed and has a large community. You can not take a risk by picking a new fancy code editor that is not used by many developers. Also, if your code editor is very heavy, then it will slow down your development process and developer experience (DX).
Simply, I can say that you can use Visual Studio Code
as your code editor. It satisfies all the requirements that I
mentioned above. It is lightweight, actively developed, has a large community, has a lot of plugins, and supports many
programming languages.
Documentation
Developers do not just write code also we write documentation. Documentation is another important part of the software development process. We can write documentation in Microsoft Word, Google Docs, etc. However, writing documentation in these tools I think is not a good practice. Maybe they can be used to document more high level things like project requirements, project plans, etc. However, writing documentation for code in these tools is not a good practice. However, keeping developer related documentation in the source code repository is good practice because;
- Its history can be tracked
- It can be versioned
- All team members can easily access it
- You do not need to switch between different tools
For this reason, the first advise that I can give is to keep your documentation in the source code repository. However, you should be careful about the format of the documentation. You should not use a binary complicated format like docx in order to track changes line by line. Instead, you should use a markup language to store your documentation.
Markdown is a very common file format that is used to write documentation. You are just creating a simple text file and you are using some special characters to format your text. Then markdown renderer will show your text in a formatted nice way. You can use markdown to write README files, project documentation, code comments, etc.
Let me summarize markdown format for you;
- To put a header to a text insert
#
character at the beginning of the title. The number of#
characters will determine the level of the header. For instance,# Header 1
will create a header 1,## Header 2
will create a header 2, etc. - To put a bold text wrap the text with
**
. For example,**Bold Text**
will create a bold text. - To put an italic text wrap the text with
*
. For instance,*Italic Text*
will create an italic text. - To put a code to a text you can use backticks.
- To put a list to a text you can use
-
character. For instance,- Item 1
,- Item 2
, etc. - To put a numbered list to a text you can use
1.
character. For instance,1. Item 1
,2. Item 2
, etc. - To put a link to a text wrap it with
[Text](URL)
format. For instance,[Google](https://www.google.com)
will create a link to Google. - To put a code block to a text you can use triple backticks. For instance,
python `print("Hello World")
- To put a quote to a text you can use
>
character. For instance,> This is a quote
If you want to learn more about markdown, you can visit Markdown Guide. I beleive that improving your markdown skills is a good idea because you will use it in your daily work.
Package Managers
What is package manager? Package manager constraints Lock files Workspaces Monorepos
Programming Language | Canonical Package Manager |
---|---|
Javascript | npm |
Typescript | npm |
Python | pip |
Java | Maven, Gradle |
C# | NuGet |
PHP | Composer |
Go | Go Modules |
Formatters
A code can be seen unclear if it is not formatted correctly. Formatting covers spaces, tabs, new lines, semicolons etc. A code formatter is a tool that automatically formats your code. Formatting means changing the code style. For instance, you can use a code formatter to change
- all double quotes to single quotes
- all tabs to spaces
- all semicolons to no semicolons
or any other code style. A code formatter is a tool that you can use to format your code. It is a good practice to use a code formatter. It will help you to keep your code clean. However, please do not forget that you need to setup your code formatter correctly. Also, different code formatting rules across different projects can be a problem. So, you need to add a configuration file to your project in order to keep your code style consistent. Also, configuration file should be under version control. So, all developers can use the same code style.
Programming Language | Canonical Formatter |
---|---|
Javascript | Prettier |
Typescript | Prettier |
Python | Black |
Java | Google Java Format |
C# | dotnet format |
PHP | PHP-CS-Fixer |
Go | Goimports |
Linters
Programming Language | Canonical Linter |
---|---|
Javascript | ESLint |
Typescript | ESLint |
Python | Pylint |
Java | Checkstyle |
C# | StyleCop |
PHP | PHP_CodeSniffer |
Go | GolangCI-Lint |
Markdown | markdownlint |
Type Checkers
Containers
A computer program is composed of two main parts: code and data. Code is the instructions that are executed by the computer. Data is the information that is processed by the code. In order to run a program, the code must be loaded into the memory. The memory is a temporary storage that is used by the CPU to store the code and data.
Code part of a program is contained in a file which is called an executable file (.exe in Windows, no common extension in Linux and MacOS). An executable file may contain cpu instructions and data that will be loaded into the memory. If the program does not need to load some data into memory before running, then the executable file can run some instructions in order to read the data from a file. Or if the program needs to store a data in a persistent way, then the program can write the data to a file. These operations are done by using operating system's system calls.
Therefore, a large program can be considered as a collection of executable files and data files (sometimes called assets, resources, etc.). However, an executable file may need a library in order to run. A library is a collection of functions that can be used by a program. These files are not executable files, but they are needed by the executable file in order to run (in Windows, they have .dll extension, in Linux they have .so extension, in MacOS they have .dylib extension). In order to run a program, the operating system must load the executable file and the libraries into the memory or the library can be loaded into the memory when the program needs it.
A static binary is an executable file that contains all the code and does not need any library in order to run. On the other hand, a dynamic binary is an executable file that needs a library in order to run. If the library is not found in the system, then the program will not run and will give an error. Also, if a library is updated, then all the programs that use this library also will be affected this change. This may cause a problem because the program may not work as expected.
A container is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries, and settings. Therefore every library that is needed by the program is included in the container. This means that the program may run in any environment that shares the same operating system kernel. This is because the container does not contain the operating system itself, but it contains the all other parts that are needed by the program.
This approach solves the problems that are mentioned above. However, it is not enough to bundle all dependencies of a program into a single package. Also we need an isolation mechanism in order to run multiple containers on the same machine in a secure way. This isolation is done by the operating system kernel. The operating system kernel is the core of the operating system that manages the hardware and provides services to the programs. The kernel is responsible for managing the memory, the CPU, the file system, the network, etc. Indeed, each process (a running instance of a program) is isolated from each other in memory. This means that a process cannot access the memory of another process by default. However, filesystem, network, etc. are shared between processes. In order to isolate these parts. Linux introduced namespaces and cgroups. By utilizing these features of the Linux kernel, containers can work on a complete isolation.
Therefore, contaieners may be used for isolation without the need of virtual machines. This comes with a significant performance improvement. For this reason, containers are widely used in the industry. However, in order to work with containers, you need some tools to build container images, run containers, and manage containers. These tools generally comes in a bundled package called container runtime.
Docker
Docker is one of the most popular container runtimes in the industry.
WIP: Container Image WIP: Container Registry WIP: Dockerfile
Docker Compose
Exercises
- Create a git repository that stores your code editor settings and plugins.
- Add commonly used plugins that is used by the community of the code editor that you are using.
- Set tab sizing and line wrapping settings.
- Add a markdown-formatted README file to your git repository
- Use headers, bold, italic, codes, lists, numbered lists, links, code blocks and quotes.
- Add a CI step to lint your markdown file by using markdownlint.
- Integrate a formatter to your repository.
- Add an npm script that formats your code. For instance,
npm run format
- Add an npm script that checks your code formatting. For instance,
npm run format:check
- Integrate the formatter with your code editor to format your code automatically when a file is saved.
- Add a CI step that checks your code formatting by running
npm run format:check
command.
- Add an npm script that formats your code. For instance,
- Integrate a linter to your repository.
- Add an npm script that lints your code. For instance,
npm run lint
- Add an npm script that checks your code linting. For instance,
npm run lint:check
- Integrate the linter with your code editor to see errors and warnings in your code editor.
- Add a CI step that checks your code linting by running
npm run lint:check
command.
- Add an npm script that lints your code. For instance,