Skip to content
This repository has been archived by the owner on Jul 31, 2023. It is now read-only.

Commit

Permalink
Merge pull request #15 from Denperidge-Redpencil/rework
Browse files Browse the repository at this point in the history
v0.1.0 Rework
  • Loading branch information
Denperidge authored May 4, 2023
2 parents d23cdc4 + 77bb174 commit 6a86bf1
Show file tree
Hide file tree
Showing 19 changed files with 670 additions and 791 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ __pycache__
docs.conf
docs/
tmp/
repos/

# Package build
dist/
Expand Down
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ Automatically collect, aggregate and structure all your [divio-style documentati
```
/{reponame}
/tutorials
/how-tos
/howtos
/explanations
/references
```

On a basic level, this repo will only need a list of git url's!

- Any input structure: this script will scan your entire repository for .md files
- If you have a how-to section in your README, that'll get extracted and put in the right spot
- Or, if you have an how-to.md file, it'll get added in its entirety!
Expand Down Expand Up @@ -52,6 +54,17 @@ The Divio structure is built upon splitting your documentation into 4 types of d

If you want to know more about the design principles of this project, feel free to check out my writeup [here](https://github.com/Denperidge-Redpencil/Learning.md/blob/main/Notes/docs.md#design-principles)!

Further expansion could be done to this project. For example, a structure like the following...
```
/{reponame}
/0.0.1
/tutorials
/how-tos
/explanations
/references
```
... should not be impossible to achieve with some tweaking!


## Reference

Expand All @@ -60,11 +73,11 @@ If you want to know more about the design principles of this project, feel free
This section is on the top of the file, and defines options that affect the entire configuration
| Parameter | Functionality |
| ------------- | -------------------------------- |
| DefaultOwner | (string) Defines which user or org has to be checked for the repository in case its Path does not explicitly define an owner |
| DefaultOwner | (string) Defines which user or org has to be checked for the repository in case its Path does not explicitly define an owner |
| GenerateNav | (boolean) Whether to add internal navigation to the top of each generated file. Defaults to `False` |
| DocsBasedir | What folder to output the docs in. Defaults to `docs/` |
| Tutorials | Sets the output folder name for tutorials. Defaults to `tutorials` |
| How-tos | Sets the output folder name for how-tos. Defaults to `how-tos` |
| Howtos | Sets the output folder name for how-tos. Defaults to `how-tos` |
| explanations | Sets the output folder name for explanations. Defaults to `explanations` |
| references | Sets the output folder name for references. Defaults to `references` |

Expand All @@ -75,17 +88,16 @@ You can add as many of these as you want. Each one represents a repo you want pa
| Parameter | Functionality |
| --------- | ------------------------------------------ |
| Path | (string) Defines which repository to parse |
| Copy | (array) Files in the repository that should be copied to a specific section. Syntax: `file.md/sectionname,file2.md/sectionname` |
| Ignore | (array) Files in the repository that should be ignored. Syntax: `file.md,file2.md` |
| Move | (string) Files in the repository that should be copied to a specific section. Syntax: `docs/file.md/section_id//file2.md/section_id/output_filename` |
| Ignore | (string) Files in the repository that should be ignored. Syntax: `file.md//file2.md` |


**Example Ignore:** `Ignore=building-a-template.md//why-semantic-microservices.md`
**Example Move:** `Move=documentation.md/references`


*Note: for `Copy` and `Ignore` you can choose to be more specific by writing `sub/folder/filename.md`. The check is a `provided_path in full_filepath`, so `sub/folder/filename.md` will apply to `even/further/sub/folder/filename.md`.*
*Note: for `Move` and `Ignore` you can choose to be more specific by writing `sub/folder/filename.md`. The check is a `provided_path in full_filepath`, so `sub/folder/filename.md` will apply to `even/further/sub/folder/filename.md`.*

##### Allowed Path syntax
You can use any of the following!
- `reponame` (if DefaultOwner is defined)
- `reponame@branch` (if DefaultOwner is defined)
- `owner/reponame`
- `owner/reponame@branch`



Expand Down
49 changes: 20 additions & 29 deletions docs.conf.example
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
[DEFAULT]
DefaultOwner=Denperidge-Redpencil
GenerateNav=True
DocsBasedir=docs/

[divio-docs-gen]
Path=divio-docs-gen

[mu-cl-resources]
Path=Denperidge-Redpencil/mu-cl-resources

[mu-project]
Path=Denperidge-Redpencil/mu-project@master

[mu-migrations-service]
Path=mu-migrations-service@master

[project]
Path=project
Copy=documentation.md/references

[mu-javascript-template]
Path=mu-javascript-template

[mu-ruby-template]
Path=mu-ruby-template

[ember-proxy-service]
Path=ember-proxy-service
[Output Configuration]
writetodisk = True
generatenav = True
docsbasedir = docs/

[Naming Scheme]
tutorials = Tutorials
howtos = How-To
explanations = Explanations
references = Reference

[Repository Selection]

[https://github.com/mu-semtech/mu-cl-resources]
url = https://github.com/mu-semtech/mu-cl-resources

[https://github.com/denperidge-redpencil/project]
url = https://github.com/denperidge-redpencil/project
Move=documentation.md/references
Ignore=building-a-template.md//why-semantic-microservices.md
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "divio_docs_gen"
version = "0.0.4"
version = "0.1.0"
authors = [
{ name="Denperidge", email="[email protected]" },
]
Expand All @@ -22,7 +22,7 @@ classifiers = [
"Bug Tracker" = "https://github.com/Denperidge-Redpencil/divio-docs-gen/issues"

[project.scripts]
divio_docs_gen = "divio_docs_gen:generate_docs"
divio_docs_gen = "divio_docs_gen:main"

[build-system]
requires = ["setuptools>=61.0"]
Expand Down
209 changes: 209 additions & 0 deletions src/divio_docs_gen/Args.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
# Native imports
from configparser import ConfigParser
from os import getcwd, path
from argparse import ArgumentParser

from .Repo import Repo

"""Code to handle configuration, through docs.conf or args"""

section_keys = ["tutorials", "howtos", "explanations", "references"]
class Args:
def __init__(self) -> None:
# store_true default is False, which means save_conf's output will be too verbose. Use None instead
self.save_conf = None
self.write_to_disk = None
self.docs_basedir = "docs/"
self.generate_nav = None

self.tutorials, self.howtos, self.explanations, self.references = section_keys

self.repos = []

def get_configured_section_name(self, section_id: str):
# TODO look for a cleaner solution
if section_id == section_keys[0]:
return self.tutorials
elif section_id == section_keys[1]:
return self.howtos
elif section_id == section_keys[2]:
return self.explanations
elif section_id == section_keys[3]:
return self.references
print(section_id)



def __str__(self) -> str:
return f"""
Configured args:
- save_conf: {self.save_conf}
- write_to_disk: {self.write_to_disk}
- docs_basedir: {self.docs_basedir}
- generate_nav: {self.generate_nav}
- tutorials: {self.tutorials}
- howtos: {self.howtos}
- explanations: {self.explanations}
- references: {self.references}
- repos: {self.repos}
"""

def __repr__(self) -> str:
return self.__str__()

args = Args()

""" Command-line args """
parser = ArgumentParser()

conf_sections = {
"output": "Output Configuration",
"naming": "Naming Scheme",
"repos": "Repository Selection"
}
ouptut_config = parser.add_argument_group(conf_sections["output"])
ouptut_config.add_argument("--save-conf",
dest="SaveConf",
help="When used, save the current command line options into ./docs.conf",
action="store_true",
default=args.save_conf,
)
ouptut_config.add_argument("--write-to-disk", "--write",
dest="WriteToDisk",
help="Whether to write the markdown to disk",
action="store_true",
default=args.write_to_disk,
)
ouptut_config.add_argument("--docs-base-dir", "--docs-dir", "--dir", "-d",
dest="DocsBasedir",
help=f"What folder to output the docs in. Defaults to `{args.docs_basedir}`",
)
ouptut_config.add_argument("--generate-nav", "--nav",
dest="GenerateNav",
help="When used, add internal navigation to the top of each generated file",
action="store_true",
default=args.generate_nav,
)
naming_scheme = parser.add_argument_group(conf_sections["naming"])
for section_key in section_keys:
short_hand = section_key[0] if section_key[0] != "h" else "ht"
naming_scheme.add_argument(f"--{section_key}", f"-{short_hand}",
dest=section_key,
help=f"Sets the output folder name for {section_key}. Defaults to `{section_key}`"
)

repo_selection = parser.add_argument_group(conf_sections["repos"])
repo_selection.add_argument("--repo",
help="""
Configures if/how a repo should be parsed
This can be defined multiple times
Syntax: --repo git_url
Example: denperidge-redpencil/project move=docs/reference/documentation.md
If none are defined, all repos will be used.
Options:
- Move: Files in the repository that should be copied to a specific section. Syntax: move=file.md/sectionname///file2.md/sectionname
- Ignore: Files in the repository that should be ignored. Syntax: ignore=file.md//file2.md
""",
action="append",
dest="repos",
nargs="*")

cli_args = parser.parse_args()
args.save_conf = bool(getattr(cli_args, "SaveConf")) if hasattr(cli_args, "SaveConf") else False

""" Conf file """
conf_file = path.join(getcwd(), "docs.conf")
use_conf = path.exists(conf_file)
if use_conf or args.save_conf:
conf = ConfigParser()
if use_conf:
conf.read("docs.conf")

for section_key in conf_sections:
section = conf_sections[section_key]
if section not in conf:
conf.add_section(section)


""" Get config, save if desired, apply"""
def get_conf_value(section_id, value_id):
return conf[section_id][value_id] if value_id in conf[section_id] else ""

def get_cli_arg_value(value_id):
return getattr(cli_args, value_id) if hasattr(cli_args, value_id) else None

def get_value(section_id, value_id, default):
"""Gets the arg, whether it be from the config file or CLI"""
# Get the value from cli if defined. Cli > conf
value = get_cli_arg_value(value_id)
# If it's undefined in the CLI, check if conf can be used
if value is None and use_conf:
value = get_conf_value(section_id, value_id)
elif value is None:
value = default

if args.save_conf:
# If it should be saved, do that
conf[section_id][value_id] = str(value)

return value

args.write_to_disk = bool(get_value(conf_sections["output"], "WriteToDisk", False))
args.generate_nav = bool(get_value(conf_sections["output"], "GenerateNav", False))
args.docs_basedir = get_value(conf_sections["output"], "DocsBasedir", "docs/")

for i, section_name in enumerate(["tutorials", "howtos", "explanations", "references"]):
# TODO cleaner solution
value = get_value(conf_sections["naming"], value_id=section_name, default=section_name)
if i == 0:
args.tutorials = value
elif i == 1:
args.howtos = value
elif i == 2:
args.explanations = value
elif i == 3:
args.references = value


if get_cli_arg_value("repos"):
for repo_arg in get_cli_arg_value("repos"):
repo = Repo(repo_arg[0])
for arg in repo_arg[1:]:
key, value = arg.split("=", 1)
key = key.lower()
if "ignore" in key:
repo.files_to_ignore += value.split("//")
elif "move" in key:
repo.files_to_move += value.split("//")

args.repos.append(repo)
conf[repo["url"]] = repo

if use_conf:
all_conf_sections = conf.sections()
for conf_section_id in all_conf_sections:
if conf_section_id in conf_sections.values(): continue

conf_section = conf[conf_section_id]
repo_data = dict(conf_section)
repo = Repo(repo_data["url"])

if "ignore" in repo_data:
repo.files_to_ignore += repo_data["ignore"].split("//")
if "move" in repo_data:
repo.files_to_move += repo_data["move"].split("//")

if repo not in args.repos:
args.repos.append(repo)


if args.save_conf:
with open("docs.conf", mode="w", encoding="UTF-8") as configfile:
conf.write(configfile)

print(args)
Loading

0 comments on commit 6a86bf1

Please sign in to comment.