Browse Source

Add developer docs (#3097)

* Create developer docs

* Remove mike dependency

* Update docs

* Make docs/dev self-contained

* Add incomplete deploy-dev-docs workflow

* Fix typo

* Add workflow file to path:

* Add doxygen as dependency

* Add remaining deploy steps

* Add working-directory

* Fix working-directory error

* Add missing Makefile

* Change flameshot website repo url

* Change working-directory for safety step

* Add git credentials

* Change push credentials

* Use different token secret

* Remove checkpoints

* Add separate branch developer-docs

* Add || true

* Update docs

* Update the 'Maintaining the documentation' docs

* Fix error in deploy-dev-docs workflow

* Remove accidentally committed file DOC.md

* Update PAT expiry date

* Rename developer-docs branch to dev-docs-staging
Haris Gušić 1 year ago
parent
commit
a2f036be9b

+ 75 - 0
.github/workflows/deploy-dev-docs.yml

@@ -0,0 +1,75 @@
+name: Deploy developer docs
+
+on:
+  push:
+    branches: [ master, docs ]
+    paths:
+      - 'src/**'
+      - 'docs/dev/**'
+      - '.github/workflows/deploy-dev-docs.yml'
+
+jobs:
+  build-and-deploy:
+    runs-on: ubuntu-22.04
+    steps:
+      - name: Install dependencies
+        run: |
+          sudo apt-get --yes --quiet update
+          sudo apt-get --yes --no-install-recommends install doxygen
+          pip install \
+              mkdocs \
+              mkdocs-material \
+              git+https://github.com/veracioux/mkdoxy@v1.0.0
+
+      - name: Checkout flameshot source
+        uses: actions/checkout@v3
+        with:
+          path: 'flameshot'
+
+      - name: Build docs
+        working-directory: ${{github.workspace}}/flameshot/docs/dev
+        run: |
+          make build
+
+      - name: Checkout flameshot website
+        uses: actions/checkout@v3
+        with:
+          repository: 'flameshot-org/flameshot-org.github.io'
+          ref: 'gh-pages'
+          path: 'website'
+
+      - name: Configure git credentials for website repo
+        working-directory: ${{github.workspace}}/website
+        run: |
+          git config user.name "GitHub Actions"
+          git config user.email "github-actions-bot@users.noreply.github.com"
+          git config http.https://github.com/.extraheader 'AUTHORIZATION basic ${{secrets.TOKEN_PUSH_TO_WEBSITE_REPO}}'
+          git remote add destination "https://x-access-token:${{secrets.TOKEN_PUSH_TO_WEBSITE_REPO}}@github.com/flameshot-org/flameshot-org.github.io"
+
+      - name: Add developer docs to website deployment
+        working-directory: ${{github.workspace}}/website
+        run: |
+          # Create empty dev-docs-staging branch
+          git checkout --orphan dev-docs-staging
+          git rm -r --cached .
+          rm -rf docs/dev
+          # Copy generated docs over
+          mkdir -p docs
+          mv "${{github.workspace}}/flameshot/docs/dev/output" \
+             "./docs/dev"
+          # Commit docs/dev to the dev-docs-staging branch
+          git add docs/dev
+          HASH="$(git --git-dir="${{github.workspace}}/flameshot/.git" rev-parse HEAD)"
+          git commit --message "Add developer docs from flameshot@$HASH"
+          # Apply changes to gh-pages
+          git checkout --force gh-pages
+          git checkout dev-docs-staging -- docs/dev
+          # Commit (we use `|| true` because the commit could be empty and thus fail)
+          git commit --message "Add developer docs from flameshot@$HASH" || true
+
+      - name: Push to website repo
+        working-directory: ${{github.workspace}}/website
+        run: |
+          git push --force destination dev-docs-staging
+          git push destination gh-pages
+

+ 3 - 0
.gitignore

@@ -72,3 +72,6 @@ data/flatpak/.flatpak-builder
 
 #MacOS Crap
 .DS_Store
+
+# Miscellaneous
+!docs/dev/Makefile

+ 2 - 0
docs/dev/.gitignore

@@ -0,0 +1,2 @@
+output
+mkdoxy-generated

+ 9 - 0
docs/dev/Makefile

@@ -0,0 +1,9 @@
+serve:
+	mkdocs serve --dev-addr localhost:8080 --watch ../../src
+build:
+	mkdocs build
+	@echo "Post-processing..."
+	@bash post-process.sh
+	@echo "DONE."
+clean:
+	rm -rf mkdoxy-generated output

+ 47 - 0
docs/dev/mkdocs.yml

@@ -0,0 +1,47 @@
+site_name: Flameshot Developer Docs
+site_url: https://flameshot.org/docs/dev/
+repo_url: https://github.com/flameshot-org/flameshot/
+edit_uri: tree/master/docs/dev/src
+docs_dir: src
+site_dir: output
+markdown_extensions:
+  - admonition
+  - attr_list
+  - toc:
+      permalink: "#"
+  - pymdownx.emoji:
+      emoji_index: !!python/name:materialx.emoji.twemoji
+      emoji_generator: !!python/name:materialx.emoji.to_svg
+
+plugins:
+  - search
+  - mkdoxy:
+      projects:
+        flameshot:
+          src-dirs: ../../src/
+          full-doc: True
+          doxy-cfg:
+            FILE_PATTERNS: "*.cpp *.h"
+            # #TODO for some reason this causes an exception
+            EXCLUDE_PATTERNS: "*/capturetool.h"
+            FULL_PATH_NAMES: "NO"
+            SHOW_USED_FILES: "NO"
+            RECURSIVE: True
+
+      save-api: mkdoxy-generated
+      debug: True
+      ignore-errors: False
+
+theme:
+  name: material
+  logo: https://flameshot.org/flameshot-icon.svg
+
+nav:
+  - Overview: index.md
+  - Debugging: debugging.md
+  - FAQ: faq.md
+  - 'Maintaining the documentation': docs.md
+  - API:
+      - Classes: flameshot/classes.md
+      - 'Class Hierarchy': flameshot/hierarchy.md
+      - Files: flameshot/files.md

+ 19 - 0
docs/dev/post-process.sh

@@ -0,0 +1,19 @@
+# Only run this script from the Makefile
+
+shopt -s globstar
+cd output
+
+# Classes backlink to the ClassList in their breadcrumbs. We use the ClassIndex
+# instead.
+rm -rf flameshot/annotated
+ln -sf classes flameshot/annotated
+
+# Hide 'Edit this page button' from the auto-generated docs pages
+# It would be better to change the button to link to the file on github, but
+# it seems like too much work right now.
+sed -i 's|title="Edit this page"|& style="display: none !important"|' flameshot/*/*.html
+
+# MkDoxy adds Qt classes into the class hierarchy. We don't want that.
+sed -i 's|<li><strong>class</strong> <strong>Q[^<]*</strong>  </li>||' flameshot/*/*.html
+
+# vim: filetype=bash

+ 16 - 0
docs/dev/src/debugging.md

@@ -0,0 +1,16 @@
+# Debugging
+
+## `FLAMESHOT_DEBUG_CAPTURE`
+
+With this cmake variable set to `ON`, the flameshot capture GUI window won't bypass the
+window manager. This allows you to manipulate the capture GUI window like any
+other window while debugging.
+
+This can be useful if a debugging breakpoint is triggered while flameshot is in
+full screen mode. Without this variable, you might have trouble inspecting the
+code due to a frozen full-screen window.
+
+Usage:
+```shell
+cmake -DFLAMESHOT_DEBUG_CAPTURE=ON ...
+```

+ 141 - 0
docs/dev/src/docs.md

@@ -0,0 +1,141 @@
+# Maintaining the documentation
+
+The narrative documentation is written in markdown and built into HTML using
+[MkDocs][mkdocs], particularly the [MkDocs material theme][mkdocs-material]. The
+source code documentation is generated using Doxygen and adapted for MkDocs
+using [MkDoxy][mkdoxy] (a tweaked custom fork of the original). The source code
+of this documentation can be found [here][doc-source].
+
+!!! tip
+
+    In order to edit a page from the documentation, click the :material-pencil:
+    button in the top right corner of the page. Please note that this button
+    won't work within the API section of the documentation - the button is
+    removed from there during [post-processing][], but it will still be visible
+    when [serving the website locally][serving-locally].
+
+## Serving locally
+To serve the documentation locally, run the `make serve` target in the
+`docs/dev` directory. The server is available at the port designated in the
+output of the command.
+
+## Notes and conventions
+- When you add new files or rename existing files or section names, be sure to
+  edit the `nav` property of [mkdocs.yml][mkdocs.yml].
+- Always insert links as [reference style
+  links][markdown:reference-style-links]. This will make the docs source code
+  more readable and make broken links more easily detectable and replaceable.
+
+### Post-processing
+There are some tweaks we make to the generated HTML documentation. We do that in
+the `make build` target, by running the [post-process.sh][post-process.sh]
+script. To see what post-processing we do, see that file.
+
+For this reason, the version of the documentation served locally using `make
+serve` will not match the generated HTML documentation 100%. But those
+inconsistencies are few and minor.
+
+## Dependencies
+```shell
+pip install \
+    mkdocs \
+    mkdocs-material \
+    git+https://github.com/veracioux/mkdoxy@v1.0.0
+```
+
+!!! note
+
+    We use a forked version of [mkdoxy][mkdoxy-original] that can be found
+    [here][mkdoxy], that fixes some annoying things from the original.
+
+## Deployment
+
+The developer documentation is served from the official Flameshot website
+[flameshot.org][website]. Here's how.
+
+The official website itself is served from this [repo][website-repo]. That repo
+contains the user documentation. It's deployed using GitHub pages -- the served
+files can be found on the [gh-pages][] branch of that repo. This branch is
+automatically created by the [build][website-build] workflow on master.
+
+To make the developer docs available on the official site, we use a custom
+GitHub action called [deploy-dev-docs][] in the [flameshot][] repo. This action
+will build and deploy this documentation into the `docs/dev` subdirectory of the
+[gh-pages][] branch.
+
+### The deploy-dev-docs GitHub workflow
+
+This workflow checks out the flameshot website [repo][website-repo] and does the following:
+
+- Creates a clean [dev-docs-staging][] branch (we'll explain why, below).
+- Generates the developer docs under `docs/dev` there and makes a commit
+- Checks out the [gh-pages][] branch and makes the same commit there
+- Force-pushes the dev-docs-staging branch to the website repo
+- Pushes the gh-pages branch to the website repo
+
+Since the [gh-pages][] branch is re-created from scratch by the [website
+deployment workflow][website-build], the commit that added the developer
+documentation will be lost. That's why we have to re-apply the commit during the
+[website deployment workflow][website-build] as well. **That is the reason why
+we created the** [**dev-docs-staging**][dev-docs-staging] **branch in the first
+place.**
+
+!!! note
+
+    The deploy-dev-docs workflow is set to run on the `docs` branch as well as `master`.
+    This branch is used for debugging the developer docs and its associated
+    workflows, without polluting the `master` branch with unnecessary commits.
+
+#### Access tokens
+In order to make changes to the [website repo][website-repo] from within a
+workflow in the [flameshot repo][flameshot], the workflow needs to use an access
+token, which it obtains from the `TOKEN_PUSH_TO_WEBSITE_REPO` secret.
+
+The following process was used to set it up:
+
+1. A flameshot organization member with write access must create a personal
+   access token (PAT) [here][PAT] with write access to the [website repo][website-repo].
+2. A secret named `TOKEN_PUSH_TO_WEBSITE_REPO` must be added to the
+   [flameshot][] repo and its value must be set to the PAT. This can be done
+   [here][action-secrets].
+
+For best security practice, the token should be set to expire after some time
+(currently ~6 months). The token can be regenerated without the need to recreate
+it. After regeneration you will need to update the `TOKEN_PUSH_TO_WEBSITE_REPO`
+secret, which can be done [here][edit-secret].
+
+!!! tip
+
+    The currently active PAT is owned by [veracioux][] and is set to expire on July
+    31 2024. If you notice the token has expired, ask him to re-generate it.
+
+<!-- Internal links -->
+[post-processing]: #post-processing
+[serving-locally]: #serving-locally
+
+<!-- Flameshot-related pages -->
+[flameshot]: https://github.com/flameshot-org/flameshot
+[website]: https://flameshot.org
+[doc-source]: https://github.com/flameshot-org/flameshot/tree/master/docs/dev
+[website-repo]: https://github.com/flameshot-org/flameshot-org.github.io
+[gh-pages]: https://github.com/flameshot-org/flameshot-org.github.io/tree/gh-pages
+[dev-docs-staging]: https://github.com/flameshot-org/flameshot-org.github.io/tree/dev-docs-staging
+[action-secrets]: https://github.com/flameshot-org/flameshot/settings/secrets/actions
+[edit-secret]: https://github.com/flameshot-org/flameshot/settings/secrets/actions/TOKEN_PUSH_TO_WEBSITE_REPO
+
+<!-- Files in flameshot repo -->
+[mkdocs.yml]: https://github.com/flameshot-org/flameshot/blob/master/docs/dev/mkdocs.yml
+[post-process.sh]: https://github.com/flameshot-org/flameshot/blob/master/docs/dev/post-process.sh
+[deploy-dev-docs]: https://github.com/flameshot-org/flameshot/blob/master/.github/workflows/deploy-dev-docs.yml
+
+<!-- Files in flameshot website repo -->
+[website-build]: https://github.com/flameshot-org/flameshot-org.github.io/blob/master/.github/workflows/build.yml
+
+<!-- External pages -->
+[markdown:reference-style-links]: https://www.markdownguide.org/basic-syntax/#reference-style-links
+[mkdocs]: https://www.mkdocs.org/
+[mkdocs-material]: https://squidfunk.github.io/mkdocs-material
+[mkdoxy-original]: https://github.com/JakubAndrysek/mkdoxy
+[mkdoxy]: https://github.com/veracioux/mkdoxy
+[PAT]: https://github.com/settings/tokens?type=beta
+[veracioux]: https://github.com/veracioux

+ 47 - 0
docs/dev/src/faq.md

@@ -0,0 +1,47 @@
+
+# FAQ
+
+!!! todo
+
+    Incomplete page.
+
+### How do I create a new subcommand?
+
+### How do I add a new tool?
+
+### How do I add a new config setting?
+
+There are currently two groups of settings: `General` and `Shortcuts`.
+The necessary steps are usually the following:
+
+- Determine a name for the setting - for a general setting, it must be a valid
+  C++ identifier, for a shortcut it must be the name of a tool type from TODO.
+- Add a getter and a setter for the setting in [`ConfigHandler`][ConfigHandler].
+  For most settings you should use the
+  [`CONFIG_GETTER_SETTER`][CONFIG_GETTER_SETTER] macro. If your setting is
+  unusual enough you may need to use [`CONFIG_GETTER`][CONFIG_GETTER] or
+  [`CONFIG_SETTER`][CONFIG_SETTER] individually, or even need to create the
+  methods manually.
+- If you need custom validation or conversion for the value, you must create a
+  subclass of [`ValueHandler`][ValueHandler]. Otherwise you can use one of the
+  existing ones in [valuehandler.h][].
+- If you want to make your setting available in the configuration GUI (usually
+  you do), you should add the appropriate widgets into one of the tabs of
+  [`ConfigWindow`][ConfigWindow]. If your setting doesn't fit into any of the
+  existing tabs, you can add a new one, but please discuss it with us first.
+
+To get a deeper understanding of how the configuration works, please see
+[Configuration][config].
+
+### How do I add a new export action? (@borgmanJeremy @mehrad This is my preferred terminology over final action, need consensus)
+
+[config]: index.md#configuration
+[confighandler.h]: flameshot/confighandler_8h
+[confighandler.cpp]: flameshot/confighandler_8cpp
+[valuehandler.h]: flameshot/valuehandler_8h
+[ValueHandler]: flameshot/classValueHandler
+[ConfigHandler]: flameshot/classConfigHandler
+[ConfigWindow]: flameshot/classConfigWindow
+[CONFIG_GETTER_SETTER]: flameshot/confighandler_8h/#define-config_getter_setter
+[CONFIG_GETTER]: flameshot/confighandler_8h/#define-config_getter
+[CONFIG_SETTER]: flameshot/confighandler_8h/#define-config_setter

+ 127 - 0
docs/dev/src/index.md

@@ -0,0 +1,127 @@
+# Flameshot developer docs
+
+Thank you for your interest in developing flameshot. This developer
+documentation (hopefully) has an intuitive structure. It tries to describe what
+code is run when a user performs an action in Flameshot.
+
+!!! important
+
+    **Please read this entire page. It will make your life a whole lot easier when
+    contributing to Flameshot. If you know exactly what you want to work on, you
+    should look at [FAQ](./faq) **
+
+## Project structure
+
+Flameshot is built on C++/Qt5 with CMake as its build system. The source code is
+located under `src/`. The entrypoint is `src/main.cpp`.
+
+### `main.cpp`
+
+Flameshot provides both a GUI and a CLI (the latter currently works only on
+Linux and macOS).
+
+### Build system
+
+The main cmake file is `CMakeLists.txt` in the project root. It `include`s some
+files from the `cmake/` directory as well. These files together control some
+more general aspects of the build process, like project information, packaging,
+caching etc.
+
+There is also the file `src/CMakeLists.txt`. It mostly defines how the source
+files are compiled into targets and how the external libraries are linked. It
+does some other stuff too. Currently, there isn't a clear separation of concerns
+between `CMakeLists.txt` and `src/CMakeLists.txt`. In the future we should
+refactor these files to make it more clear why each of them exists.
+
+## What happens when I launch flameshot?
+There are two ways to launch flameshot: daemon mode and single-action mode. In
+both modes, an instance of [`Flameshot`][Flameshot] is created via
+[`Flameshot::start()`][Flameshot::start]. [`Flameshot`][Flameshot] provides the
+high level API for interacting with flameshot; and its methods mimic the CLI
+subcommands a great deal. This object is a singleton, so it can only be created
+once. It is accessed as [`Flameshot::instance()`][Flameshot::instance].
+
+!!! note
+
+    On Windows, only daemon mode is currently supported.
+
+### Single-action mode (via command line interface)
+Single-action mode (also called one-off mode) is triggered when flameshot is
+launched with a command line argument - for example as `flameshot gui`. As its
+name implies, it performs a single action, such as "take a screenshot
+interactively by opening a GUI" or "take a screenshot of the entire screen",
+etc. Afterwards, Flameshot quits.
+
+### Daemon mode
+This mode is triggered when the `flameshot` command is launched. In this mode, a
+flameshot process is started in the background. A system tray is displayed if
+the user hasn't disabled it in the config. In addition to [`Flameshot::start()`][Flameshot::start],
+if the current process is the daemon, it also calls [`FlameshotDaemon::start()`][FlameshotDaemon::start]
+during initialization.
+
+The daemon has the following purposes:
+
+- Run in the background, wait for the user to press a hotkey, and perform
+  corresponding action.
+
+    This is true for **Windows** and **macOS**, but not for **Linux**. On Linux, hotkeys
+    are meant to be handled by the desktop environment or equivalent.
+
+- Provide a system tray that the user can click to initiate actions via context
+  menu
+
+- Periodically check for updates and notify the user
+
+- Act as a host for persistent phenomena. Example: On X11 (linux), when a program
+  inserts content into the clipboard, it must keep running so the content
+  persists in the clipboard.
+
+!!! note
+
+    All of the above are user-configurable.
+
+#### `FlameshotDaemon`
+The class [`FlameshotDaemon`][FlameshotDaemon] handles all communication with
+the daemon. The class provides public static methods that are designed so that
+the caller does not need to know if the current process is a flameshot daemon or
+a single-action invocation of Flameshot. If the current process is the daemon,
+then the static methods of [`FlameshotDaemon`][FlameshotDaemon] will call the
+corresponding instance methods of the singleton. If not, the current process
+will communicate with the daemon process via D-Bus. Then, within the daemon
+process, those D-Bus calls will be translated into
+[`FlameshotDaemon`][FlameshotDaemon] instance method calls.
+
+## Configuration
+The configuration is handled by [`ConfigHandler`][ConfigHandler]. It is
+decoupled from any user interface, so it serves the configuration for both the
+GUI and CLI. All configuration settings recognized by the config files are
+defined as getters in this class. There are also setters for each setting, named
+as per the usual convention. For example, the setting `savePath` has a getter
+named `savePath` and a setter named `setSavePath`. Before working on a new
+config setting for flameshot, please read [this FAQ
+entry][faq:add-config-setting].
+
+### Interesting notes
+
+- [`ConfigHandler`][ConfigHandler] is based on `QSettings`
+- The configuration uses the `ini` format
+- The configuration is automatically reloaded when the config file changes
+
+## Conventions
+
+- Always use `&Class::signal` and `&Class::slot` instead of `SIGNAL(signal())`
+  and `SLOT(slot())`. This usually provides better code introspection and makes
+  refactoring easier and less error-prone.
+
+[Flameshot]: flameshot/classFlameshot
+[Flameshot::instance]: flameshot/classFlameshot#function-instance
+[Flameshot::start]: flameshot/classFlameshot#function-start
+[ConfigHandler]: flameshot/classConfigHandler
+[FlameshotDaemon]: flameshot/classFlameshotDaemon
+[FlameshotDaemon::start]: flameshot/classFlameshotDaemon#function-start
+[confighandler.h]: flameshot/confighandler_8h
+[confighandler.cpp]: flameshot/confighandler_8cpp
+
+[faq:add-config-setting]: faq/#how-do-i-add-a-new-config-setting
+
+[matrix-room]: https://matrix.to/#/#flameshot-org:matrix.org