Skip to content

Commit

Permalink
Merge branch '15-create-examples' into 'master'
Browse files Browse the repository at this point in the history
Resolve "Create examples"

Closes #15

See merge request ShellLogger/ShellLogger!7
  • Loading branch information
jmgate committed Sep 22, 2021
2 parents 8f4c88a + c478b3c commit 3a5a282
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 24 deletions.
87 changes: 68 additions & 19 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ cache: &global_cache
# Set up the pipeline stages.
stages:
- prepare
- test
- install
- examples
- test
- documentation
- deploy
- finish
Expand Down Expand Up @@ -51,6 +50,11 @@ after_script:
fi
#-----------------------------------------------------------------------
# Stage: Prepare
#-----------------------------------------------------------------------


# Create the virtual environment, install the requirements, and save the
# environment to the cache.
install requirements:
Expand Down Expand Up @@ -79,6 +83,44 @@ install requirements:
-r doc/requirements.txt


#-----------------------------------------------------------------------
# Stage: Install
#-----------------------------------------------------------------------


# Test building a distribution.
build distribution:
stage: install
needs: ["install requirements"]
timeout: 5m
cache:
<<: *global_cache
policy: pull
script:
- python3 -m pip wheel --no-deps -w dist .
artifacts:
name: "shelllogger-dist"
paths:
- dist/shelllogger*.whl
expire_in: 6 weeks


# Test installation of the package.
install package:
stage: install
needs: ["install requirements"]
timeout: 5m
cache:
<<: *global_cache
script:
- python3 -m pip install .


#-----------------------------------------------------------------------
# Stage: Test
#-----------------------------------------------------------------------


# Execute the unit tests.
pytest:
stage: test
Expand Down Expand Up @@ -116,32 +158,29 @@ flake8:
--exclude=venv-clean-python


# Test building a distribution.
build distribution:
stage: install
needs: ["install requirements"]
# Ensure the examples run without problems.
examples:
stage: test
needs: ["install requirements", "install package"]
timeout: 5m
cache:
<<: *global_cache
policy: pull
script:
- python3 -m pip wheel --no-deps -w dist .
- cd examples
- python3 -m pip list
- python3 ./hello_world_html.py
- python3 ./hello_world_html_and_console.py
- python3 ./hello_world_html_with_stats.py
- python3 ./build_flex.py
artifacts:
name: "shelllogger-dist"
paths:
- dist/shelllogger*.whl
expire_in: 6 weeks
- examples/log*


# Test installation of the package.
install package:
stage: install
needs: ["install requirements"]
timeout: 5m
cache:
<<: *global_cache
script:
- python3 -m pip install .
#-----------------------------------------------------------------------
# Stage: Documentation
#-----------------------------------------------------------------------


# Generate the documentation.
Expand All @@ -159,6 +198,11 @@ sphinx:
- doc/html


#-----------------------------------------------------------------------
# Stage: Deploy
#-----------------------------------------------------------------------


# Publish coverage data and documentation (if on the main branch).
pages:
stage: deploy
Expand All @@ -178,6 +222,11 @@ pages:
- public


#-----------------------------------------------------------------------
# Stage: Finish
#-----------------------------------------------------------------------


# Test that uninstalling from a virtual environment works.
uninstall package:
stage: finish
Expand Down
2 changes: 1 addition & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added doc/source/images/expand_command_card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/images/expand_details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/images/expand_diagnostics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/images/html_log.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/source/images/log_dir_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 100 additions & 4 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,107 @@ These data are collected in a "log book". When you call
:func:`ShellLogger.finalize`, the contents of the log book are written to a
HTML log file.

Example
^^^^^^^
Example 1: The Basics
^^^^^^^^^^^^^^^^^^^^^^

.. todo::
This first example demonstrates the bare-bones basics of ``shelllogger``, in
which we're logging commands only to the HTML log file.

Insert simplest example here, and link to other examples in the repo.
.. literalinclude:: ../../examples/hello_world_html.py
:language: python
:linenos:
:caption: ``examples/hello_world_html.py``

Running the script yields

.. code-block::
This example demonstrates logging information solely to the HTML log file.
Open /Users/jmgate/workspace/ShellLogger/examples/log_hello_world_html/2021-09-22_14.56.42.558599_szt68acx/Hello_ShellLogger.html to view the log.
When you open the HTML log file, you'll see something like

.. image:: images/html_log.png
:alt: HTML log file
:align: center

When you first open the log file, most of the content will be collapsed. You
can click on any of the commands to expand it.

.. image:: images/expand_command_card.png
:alt: Expanding the command card
:align: center

Here you can see some details, along with ``stdout`` and ``stderr``. Clicking
on **Details** yields even more information:

.. image:: images/expand_details.png
:alt: Expanding the Details section
:align: center

Similarly, clicking **Diagnostics** gives you even more information:

.. image:: images/expand_diagnostics.png
:alt: Expanding the Diagnostics section
:align: center

Note that some of the cards allow you to search the output via a regular
expression, which can be really helpful when debugging.

If you look inside the log directory that's created by :class:`ShellLogger`,
you'll see the following:

.. image:: images/log_dir_tree.png
:alt: Log directory structure
:align: center

First you'll see a timestamped log directory. Any future runs of the script
will create additional timestamped log directories as siblings. This is to
ensure you never accidentally overwrite a prior log. Within the timestamped
log directory, you'll notice a number of files that contain the ``stdout`` and
``stderr`` streams from the commands that were executed. Then there's the
HTML log file itself, which you can open in a browser, and finally a JSON log
file that's used to construct the HTML log file, mapping the commands to their
output streams. The last item is a symbolic link to the latest HTML log file.
If the script is run multiple times, this link is updated to always point to
the latest log.

Example 2: Simultaneous Logging to the Console
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This next example demonstrates logging commands both to the HTML log file and
the console. The primary differences between this and **Example 1** are the
highlighted lines below.

.. literalinclude:: ../../examples/hello_world_html_and_console.py
:language: python
:linenos:
:emphasize-lines: 11, 13
:caption: ``examples/hello_world_html_and_console.py``

Example 3: Collecting Statistics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In this example, we demonstrate how easy it is to capture various statistics
while running your commands in the shell. The primary differences between this
and **Example 1** are the highlighted lines below.

.. literalinclude:: ../../examples/hello_world_html_with_stats.py
:language: python
:linenos:
:emphasize-lines: 12, 14
:caption: ``examples/hello_world_html_with_stats.py``

Example 4: Building a Code
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In this final example, we use ``shelllogger`` to do some "real work"---cloning,
configuring, and building `flex </~https://github.com/westes/flex.git>`_, a fast
lexical analyzer generator.

.. literalinclude:: ../../examples/build_flex.py
:language: python
:linenos:
:caption: ``examples/build_flex.py``

For more detailed usage information, see the :doc:`ShellLogger`.
2 changes: 2 additions & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
log*
flex*
26 changes: 26 additions & 0 deletions examples/build_flex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env python3

from pathlib import Path
from shelllogger import ShellLogger

sl = ShellLogger("Build Flex",
Path.cwd() / f"log_{Path(__file__).stem}")
sl.print("This example demonstrates cloning, configuring, and building the "
"Flex tool.")
sl.log("Clone the Flex repository.",
"git clone --depth 1 --branch flex-2.5.39 "
"/~https://github.com/westes/flex.git flex-2.5.39", live_stdout=True,
live_stderr=True)
sl.log("Run Autogen", "./autogen.sh", cwd=Path.cwd()/"flex-2.5.39",
live_stdout=True, live_stderr=True)
sl.log("Configure Flex", "./configure --prefix=$(dirname $(pwd))/flex",
cwd=Path.cwd()/"flex-2.5.39", live_stdout=True, live_stderr=True,
measure=["cpu", "memory", "disk"])
sl.log("Build libcompat.la", "make libcompat.la",
cwd=Path.cwd()/"flex-2.5.39/lib", live_stdout=True, live_stderr=True,
measure=["cpu", "memory", "disk"])
sl.log("Build & Install Flex", "make install-exec",
cwd=Path.cwd()/"flex-2.5.39", live_stdout=True, live_stderr=True,
measure=["cpu", "memory", "disk"])
sl.finalize()
print(f"Open {sl.html_file} to view the log.")
14 changes: 14 additions & 0 deletions examples/hello_world_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python3

from pathlib import Path
from shelllogger import ShellLogger

sl = ShellLogger("Hello ShellLogger",
Path.cwd() / f"log_{Path(__file__).stem}")
sl.print("This example demonstrates logging information solely to the HTML "
"log file.")
sl.log("Greet everyone to make them feel welcome.", "echo 'Hello World'")
sl.log("Tell everyone who you are, but from a different directory.", "whoami",
cwd=Path.cwd().parent)
sl.finalize()
print(f"Open {sl.html_file} to view the log.")
15 changes: 15 additions & 0 deletions examples/hello_world_html_and_console.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env python3

from pathlib import Path
from shelllogger import ShellLogger

sl = ShellLogger("Hello ShellLogger",
Path.cwd() / f"log_{Path(__file__).stem}")
sl.print("This example demonstrates logging information both to the HTML log "
"file and to the console simultaneously.")
sl.log("Greet everyone to make them feel welcome.", "echo 'Hello World'",
live_stdout=True, live_stderr=True)
sl.log("Tell everyone who you are, but from a different directory.", "whoami",
cwd=Path.cwd().parent, live_stdout=True, live_stderr=True)
sl.finalize()
print(f"Open {sl.html_file} to view the log.")
16 changes: 16 additions & 0 deletions examples/hello_world_html_with_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env python3

from pathlib import Path
from shelllogger import ShellLogger

sl = ShellLogger("Hello ShellLogger",
Path.cwd() / f"log_{Path(__file__).stem}")
sl.print("This example demonstrates logging information solely to the HTML "
"log file, while collecting CPU, memory, and disk statistics at the "
"same time.")
sl.log("Greet everyone to make them feel welcome.", "echo 'Hello World'",
measure=["cpu", "memory", "disk"])
sl.log("Tell everyone who you are, but from a different directory.", "whoami",
cwd=Path.cwd().parent, measure=["cpu", "memory", "disk"])
sl.finalize()
print(f"Open {sl.html_file} to view the log.")

0 comments on commit 3a5a282

Please sign in to comment.