Giter Site home page Giter Site logo

backstage / mkdocs-monorepo-plugin Goto Github PK

View Code? Open in Web Editor NEW
305.0 23.0 72.0 3.38 MB

✚ Build multiple documentation folders in a single Mkdocs. Designed for large codebases.

Home Page: https://backstage.github.io/mkdocs-monorepo-plugin/

License: Apache License 2.0

Shell 39.77% Python 60.23%
documentation mkdocs plugin monoliths monorepos mkdocs-monorepo-plugin

mkdocs-monorepo-plugin's Introduction

headline

English | 한국어 | 中文版

License CNCF Status Discord Code style Codecov Uffizzi OpenSSF Best Practices OpenSSF Scorecard

What is Backstage?

Backstage is an open source framework for building developer portals. Powered by a centralized software catalog, Backstage restores order to your microservices and infrastructure and enables your product teams to ship high-quality code quickly without compromising autonomy.

Backstage unifies all your infrastructure tooling, services, and documentation to create a streamlined development environment from end to end.

software-catalog

Out of the box, Backstage includes:

  • Backstage Software Catalog for managing all your software such as microservices, libraries, data pipelines, websites, and ML models
  • Backstage Software Templates for quickly spinning up new projects and standardizing your tooling with your organization’s best practices
  • Backstage TechDocs for making it easy to create, maintain, find, and use technical documentation, using a "docs like code" approach
  • Plus, a growing ecosystem of open source plugins that further expand Backstage’s customizability and functionality

Backstage was created by Spotify but is now hosted by the Cloud Native Computing Foundation (CNCF) as an Incubation level project. For more information, see the announcement.

Project roadmap

For information about the detailed project roadmap including delivered milestones, see the Roadmap.

Getting Started

To start using Backstage, see the Getting Started documentation.

Documentation

The documentation of Backstage includes:

Community

To engage with our community, you can use the following resources:

License

Copyright 2020-2024 © The Backstage Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage

Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0

Security

Please report sensitive security issues using Spotify's bug-bounty program rather than GitHub.

For further details, see our complete security release process.

mkdocs-monorepo-plugin's People

Contributors

agentbellnorm avatar aladjadj avatar bih avatar blueswen avatar bodilb avatar camilaibs avatar captainsafia avatar dariocurr avatar diegomarangoni avatar haneul avatar hooloovooo avatar iameap avatar jacobvaldemar avatar lewiseason avatar nerdoc avatar orkohunter avatar ottosichert avatar preisschild avatar realandersn avatar richardmcsong avatar rwittrick avatar soapraj avatar teamteatime avatar timvink avatar walter-maldonado avatar waltermaldonado avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mkdocs-monorepo-plugin's Issues

Internal Markdown links in included folder not converted to HTML when pointing outside included folder

Your tool is awesome, and thanks for open sourcing it! It solves a very common problem.

I'm using:

mkdocs 1.0.4
mkdocs-monorepo-plugin 0.4.3

I have a pretty basic setup:

  • a primary docs folder with a primary mkdocs.yml
  • a secondary docs folder with a mkdocs.yml that I'm including in the primary mkdocs.yml

In the secondary docs folder, I have a page where I am trying to create a Markdown link to a page in the primary docs folder. I do so with something like:
[MyLink](MyLink.md)
I'm assuming it is possible to get back to the root this way (I have also tried /MyLink.md).

However, the resulting link is not correctly being converted to HTML when the site is built. It comes out to be:
<a href="MyLink.md">MyLink</a>

With the .md extension, the link is then not found. For included folders, it seems like the build is not aware when internal links are pointing outside of that included folder. The only way to get around this is using an HTML link.

Thanks much!

Error since pull request #74

Hi

I just updated the monorepo plugin and the before working project now fails to serve/build. I could drill down the issue to the pull request #74 which added the edit_uri.py file.

When I comment the call set_edit_url(config, page, self) in the file plugin.py on line 71 the project builds fine.

The edit_uri is not set in my environment and even when setting it something it does not build. The problem seems to have a dependency to the mkdocs-static-i18n plugin that we also use. I don't know if the root cause of the problem is in th2 i18n plugin or in the mono repo plugin. The issue occured after updating the monorepo plugin.

It would be great if you could add some check to the code to skip the edit-url thing when there is no edit-url set to fix this for cases like mine. Below I attached the Treaceback to narrow the issue.

What do you think?

Thanks for your work and thoughts about this issue

Regards
Florian

ERROR    -  Error reading page 'manual_dev/index.md': join() missing 1 required positional argument: 'a'
Traceback (most recent call last):
  File "/opt/homebrew/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/opt/homebrew/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/__main__.py", line 236, in <module>
    cli()
  File "/opt/homebrew/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/opt/homebrew/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/homebrew/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/homebrew/lib/python3.9/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/__main__.py", line 181, in serve_command
    serve.serve(dev_addr=dev_addr, livereload=livereload, watch=watch, **kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 63, in serve
    config = builder()
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/commands/serve.py", line 58, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/commands/build.py", line 317, in build
    config['plugins'].run_event('post_build', config=config)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/plugins.py", line 104, in run_event
    result = method(**kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_static_i18n/plugin.py", line 622, in on_post_build
    _populate_page(file.page, config, files, dirty)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/commands/build.py", line 163, in _populate_page
    page = config['plugins'].run_event(
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs/plugins.py", line 102, in run_event
    result = method(item, **kwargs)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/plugin.py", line 71, in on_pre_page
    set_edit_url(config, page, self)
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 104, in set_edit_url
    page.edit_url = edit_url.build()
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 97, in build
    if self.__has_repo():
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 85, in __has_repo
    page_config_file_yaml = self.__get_page_config_file_yaml()
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 80, in __get_page_config_file_yaml
    abs_page_config_file_path = self.__get_page_config_file_path()
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 51, in __get_page_config_file_path
    alias = self.__get_page_dir_alias()
  File "/opt/homebrew/lib/python3.9/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 35, in __get_page_dir_alias
    alias = path.join(*parts)
TypeError: join() missing 1 required positional argument: 'a'

monorepo with submodules (empty)

Hi,

I am playing with monorepo plugin.
I have 1 repo (rpa-doc) with 2 submodules (rpa-1, rpa2):

rpa-doc
- docs \ README.md
- .gitmodules
- catalog-info.yml
- mkdocs.yml
- rpa-1 @ d70d...
- rpa-2 @ dbe6...

mkdocs.yml

site_name: RPA Documentation (Test)

nav:
  - Home: README.md
  - Submodules:
    - rpa-1: '!include ./rpa-1/mkdocs.yml'
    - rpa-2: '!include ./rpa-2/mkdocs.yml'

plugins:
  - monorepo

rpa-1 @ d70d...

- docs \ README.md
- mkdocs.yml

When backstage executes the doc generation:

[mkdocs-monorepo] The file path /tmp/backstage-QFfxej/rpa-1/mkdocs.yml does not exist, is not valid YAML, or does not contain a valid 'site_name' and 'nav' keys.

And /tmp/backstage-QFfxej/rpa-1/mkdocs.yml does not exist.
=> Submodules folders are empty.

I think the clone action does not use the --recursive attribute.

Locally:

git clone https://bitbucket.[xxx].[xxx]/scm/tests/rpa-doc.git --recursive

=> [OK] submodules are pulled and mkdocks.yml files exist.

git clone https://bitbucket.[xxx].[xxx]/scm/tests/rpa-doc.git

=> [KO] submodules are empty

Any idea?
Thanks!

mkdocs_build_plantuml will not work when monorepo enabled

Dear all,

I find find out that plugin https://github.com/christo-ph/mkdocs_build_plantuml will not work correctly with monorepo.
Problem is that generated SVG/PNG will not be moved to the source folder. Related ticket quantorconsulting/mkdocs_build_plantuml#9

How to reproduce:

  1. Enable monorepo and plantuml build:
theme:
  name: 'material'

site_dir: source

plugins:
  - build_plantuml:
      render: "local"
      bin_path: "/usr/bin/plantuml"
      output_format: "svg"
      diagram_root: "docs/diagrams"
      output_folder: "out"
      input_folder: "src"
  - monorepo
  1. Create puml file in docs\diagrams\src\, e.g. system_quick_overview.puml with content:
@startuml
Bob -> Alice : hello
@enduml
  1. Run build.
mkdocs build
INFO    -  Cleaning site directory 
INFO    -  Building documentation to directory: /source 
INFO    -  Number headings up to level 3. 
INFO    -  Generate a table of contents up to heading level 2. 
INFO    -  Generate a cover page with "default_cover.html.j2". 
INFO    -  Converting <img> alignment(workaround). 
ERROR   -  Failed to load image at "file:///source/catalog/diagrams/out/system_quick_overview.svg" (URLError: <urlopen error [Errno 2] No such file or directory: '/source/catalog/diagrams/out/system_quick_overview.svg'>)
INFO    -  Documentation built in 10.39 seconds 
Converting /docs/diagrams/src/system_quick_overview.puml

ls -laR source/diagrams
./source/diagrams:
total 12
drwxr-xr-x    3 root     root          4096 May 17 13:31 .
drwxr-xr-x   15 root     root          4096 May 17 13:31 ..
drwxr-xr-x    2 root     root          4096 May 17 13:31 src
./source/diagrams/src:
total 12
drwxr-xr-x    2 root     root          4096 May 17 13:31 .
drwxr-xr-x    3 root     root          4096 May 17 13:31 ..
-rw-r--r--    1 root     root           474 May 17 13:31 system_quick_overview.puml

# NO Folder "out"

Nether folder, or files inside will be moved to source folder. But they exist in docs folder:

ls -laR /docs/diagrams
./docs/diagrams:
total 16
drwxrwxrwx    4 root     root          4096 May 17 13:30 .
drwxrwxrwx   12 root     root          4096 May 17 13:05 ..
drwxr-xr-x    2 root     root          4096 May 17 13:30 out
drwxrwxrwx    2 root     root          4096 May 17 13:05 src
./docs/diagrams/out:
total 16
drwxr-xr-x    2 root     root          4096 May 17 13:30 .
drwxrwxrwx    4 root     root          4096 May 17 13:30 ..
-rw-r--r--    1 root     root          6884 May 17 13:31 system_quick_overview.svg
./docs/diagrams/src:
total 12
drwxrwxrwx    2 root     root          4096 May 17 13:05 .
drwxrwxrwx    4 root     root          4096 May 17 13:30 ..
-rw-rw-rw-    1 root     root           474 May 17 13:05 system_quick_overview.puml
  1. Disable monorepo and run build. Test that it succeed.
mkdocs build
INFO    -  Cleaning site directory 
INFO    -  Building documentation to directory: /source 
INFO    -  Number headings up to level 3. 
INFO    -  Generate a table of contents up to heading level 2. 
INFO    -  Generate a cover page with "default_cover.html.j2". 
INFO    -  Converting <img> alignment(workaround). 
INFO    -  Documentation built in 20.54 seconds 
Converting /docs/diagrams/src/system_quick_overview.puml

ls -la source/diagrams
./source/diagrams:
total 16
drwxr-xr-x    4 root     root          4096 May 17 13:34 .
drwxr-xr-x   15 root     root          4096 May 17 13:34 ..
drwxr-xr-x    2 root     root          4096 May 17 13:34 out
drwxr-xr-x    2 root     root          4096 May 17 13:34 src
./source/diagrams/out:
total 16
drwxr-xr-x    2 root     root          4096 May 17 13:34 .
drwxr-xr-x    4 root     root          4096 May 17 13:34 ..
-rw-r--r--    1 root     root          6884 May 17 13:34 system_quick_overview.svg   #THIS IS A FILE
./source/diagrams/src:
total 12
drwxr-xr-x    2 root     root          4096 May 17 13:34 .
drwxr-xr-x    4 root     root          4096 May 17 13:34 ..
-rw-r--r--    1 root     root           474 May 17 13:34 system_quick_overview.puml

searching on numbers

Thank you for creating this plugin.

We are using it to connect multiple MkDocs sites as one big help system for our users.

We want to search on numbers like 2020 or X2GO. So we changed the regular expression for wordCharacters in /usr/local/lib/python3.8/site-packages/mkdocs/contrib/search/lunr-language/lunr.nl.js and /usr/local/lib/python3.8/site-packages/material/assets/javascripts/lunr/min/lunr.nl.min.js to include numbers. This works fine with a single MkDocs site. However when we use it with monorepo this does not work. Can you fix this?

Allow for spaces in site_name of sub-docs

Hi, currently the plugin fails if any of sub-projects' site name include whitespaces. The assumption is to use that name just to generate an URL, because we show the root site name anyway, so whitespaces seem redundant. However:

  • when you move some repository to monorepo - you need to remember to edit the site_name, because it would fail otherwise
  • if you want to generate a mkdocs site just for given sub-project (e.g. you work on a sub-project workspace in VS Code) - you get an ugly site title with dashes / underscores / slashes

Imho it can be fixed easily - instead of forbidding whitespaces, let's just replace them with underscores automatically by plugin when reading the config values. This way we don't introduce any breaking changes and we make the transition to monorepo even easier 😉

❯ mkdocs serve
INFO     -  Building documentation...
[mkdocs-monorepo] Site name can only contain letters, numbers, underscores, hyphens and forward-slashes. The regular expression we test against is '^[a-zA-Z0-9_\-/]+$'.

Running tests fail

Hi,

Do you happen to know why the following test might fail?

tly cleaning up <TemporaryDirectory '/tmp/guix-build-python-mkdocs-monorepo-plugin-1.0.4.drv-0/docs_ez27_kvk'>
  _warnings.warn(warn_message, ResourceWarning)
test_plugin_on_serve (mkdocs_monorepo_plugin.tests.test_plugin.TestMonorepoPlugin) ... ok
test_plugin_on_serve_no_run (mkdocs_monorepo_plugin.tests.test_plugin.TestMonorepoPlugin) ... ok

======================================================================
ERROR: test_plugin_on_config_with_nav (mkdocs_monorepo_plugin.tests.test_plugin.TestMonorepoPlugin)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/guix-build-python-mkdocs-monorepo-plugin-1.0.4.drv-0/mkdocs-monorepo-plugin-1.0.4/mkdocs_monorepo_plugin/tests/test_plugin.py", line 25, in test_plugin_on_config_with_nav
    plugin.on_config({
  File "/tmp/guix-build-python-mkdocs-monorepo-plugin-1.0.4.drv-0/mkdocs-monorepo-plugin-1.0.4/mkdocs_monorepo_plugin/plugin.py", line 52, in on_config
    new_docs_dir = self.merger.merge()
  File "/tmp/guix-build-python-mkdocs-monorepo-plugin-1.0.4.drv-0/mkdocs-monorepo-plugin-1.0.4/mkdocs_monorepo_plugin/merger.py", line 74, in merge
    raise SystemExit(1)
SystemExit: 1

----------------------------------------------------------------------
Ran 4 tests in 0.003s

Enhancement - allow include to point to Git URL for mkdocs.yml & docs in other repos

Oooh wouldn't this be so cool... :)

So you mention the ability to use git submodules to include the mkdocs.yml + docs in other repositories. If these sub-repos (let's call them) are standalone mkdocs directories without any developer code, this works.

However, let's say you have a bunch of dev code in a sub-repo, but you also want to have the documentation live there in a 'docs' folder. And then you have several of these sub-repos with separate docs folders. This sort of distributed system is great because the docs live alongside the code (docs-as-code), and developers can make changes to their code and documentation with a single commit, but still have a central mkdocs build for ALL the documentation.

The problem with git submodules is they inherently bring over the entire repository, not a single directory. In the scenario above using submodules, all the code would be brought over alongside any documentation. This is quite a bit of bloat, and you would have to then solve for excluding all the code from your docs build. Submodules are also a bit messy anyways, particularly for tech writers or folks not familiar.

What would be ideal is to have separate "docs" directories in each sub-repo, and only bring over that specific folder into the primary docs build at the time of the build. I'm currently using a Git overlay tool called Gilt in the mkdocs build to solve for this very problem.

It would be nice to have this functionality included in your tool - allow the mkdocs.yml include function point to a Git URL of a mkdocs.yml + docs in another repo (making sure to point to the right folder and branch). Then everything can be brought together for the primary mkdocs build.

I betcha this would help your own documentation flow too ;)

This plugin is broken for sphinx >= 4.0

The Signature class is no longer defined in sphinx/util/inspect.py

Which means that using this plugin yields this error:
ImportError: cannot import name 'Signature' from 'sphinx.util.inspect' (/usr/local/lib/python3.8/dist-packages/sphinx/util/inspect.py

Just letting you guys know.

So I pinned the version to 3.5.4 to make it work for me.

Support for different repos for referencing

Currently we use this mkdocs-core-container for our backstage instance.
One of the drawback we have is that there is support for only two plugins search and mono repo.
With mono repo plugin, it currently doesn't allow us to refer to the mkdocs.yaml from different repos.

Do you have plans to support either
1>plugins such as mkdocs-multirepo-plugin
2>different repo's under mkdocs-monorepo-plugin

Check whether the page source is in this plugins control

If another plugin modifies the sources, it's not always true that this plugins files_source_dir dict will always contain the page.file.abs_src_path, and therefore this might throw an error:

From

page.file.abs_src_path = self.files_source_dir[page.file.abs_src_path]

    def on_pre_page(self, page, config, files):
        # Update page source attribute to point to source file
        # Only in case any files were moved.
        if len(self.files_source_dir) > 0:
            page.file.abs_src_path = self.files_source_dir[page.file.abs_src_path]
        return page

This code should check whether it was "managing" the source for the page via

 if len(self.files_source_dir) > 0 && page.file.abs_src_path in self.files_source_dir:

before trying to change it (at Line 62 of plugin.py)

How to implement i18n or different languages support in better way?

Hello dear community,

Just wondering how it is in a better way to implement i18n support with monorepo. I can use plugin or mkdocs material feature and it works fine. But when I collect different repos with monorepo, it somehow does not work anymore on attached repositories.
Do you have an idea, guide or something to help in this area?

Kind Regards,
Georgiy

Question on limitations - nested documentation projects

Hello,

The documentation on Limitations states that "In an included mkdocs.yml, you cannot have !include. It is only supported in the root mkdocs.yml".

I would like to know if this is a design decision or a limitation that could be addressed in the future?

Question: *include

Does the *include work only as the highest level list and not under secondary level?

For example: this works
nav:

  • Main topic: '*include:...'

this doesn't work:
nav:

  • Main topic:
    • intro: "index.md"
    • Sub topic: "*include..."

Suggestion: Allow any config file name

Currently, monorepo only supports including MkDocs config files that are named exactly mkdocs.yml.

However, it can be useful to have multiple config files, especially when working with projects that are built both individually and as part of a multirepo. In this case, the default "standalone" config file would ideally be named mkdocs.yml, and the monorepo version would have a different name, e.g., mkdocs-monorepo.yml.

So I suggest to get rid of this limitation and support any *.yml file. I think this could be achieved quite easily:

  1. Adapt the regex that matches the config file name:
    rootDir, re.sub(r'\/mkdocs.yml$', '', path, re.IGNORECASE)))
rootDir, re.sub(r'(.*)\/.*\.yml$', r'\1', path, re.IGNORECASE)))
  1. Adapt read():
    if not self.absNavPath.endswith("mkdocs.yml"):
if not self.absNavPath.endswith(".yml"):

Any thoughts? Should I submit a PR for this?

mkdocs serve not working on mkdocs 1.2

I updated my current virtual env to use mkdocs 1.2 (i'm testing the new analytics feature since i can't generate a UA-XXXXXX to use with older versions) and i get an error at the end of the building while serving (mkdocs build works fine):

File ".venv/lib/python3.6/site-packages/mkdocs_monorepo_plugin/plugin.py", line 67, in on_serve
    buildfunc = list(server.watcher._tasks.values())[0]['func']
AttributeError: 'LiveReloadServer' object has no attribute 'watcher'

Redirected from mkdocs/mkdocs#2446 (comment)

Broken version 0.4.9

The new version v0.4.9 is broken for me. Using macOS and mkdocs==1.1.2. To reproduce:

pip install --upgrade mkdocs-monorepo-plugin
cd mkdocs-monorepo-plugin/sample-docs
mkdocs serve

And then browse to the v1 page:

image

Error when no `nav` and `docs_dir` are specified

I was trying to build my monorepo documentation having the following in the general mkdocs.yml

site_name: "Example"
site_description: "Description Here"

docs_dir: ./docs

plugins:
  - monorepo

nav:
  - Home: "index.md"
  - Subnav:
    - index.md
    - index.md
  - Hello: "!include project-a/mkdocs.yml"

and the following mkdocs.yml in a subfolder of the monorepo

site_name: "test"
site_description: "This is a subdomain site."

plugins:
  - monorepo

And I got this error:

The file path .... does not contain a valid 'nav' key in the YAML file and the docs folder is not the default one, i.e. docs. Please include the nav key to indicate how your documentation should be presented in the navigation, or include a 'docs_dir' to indicate that automatic nav generation should be used.

I personally find useless to specify the key docs_dir when it is the default one, i.e. docs.
I would like to have the automatic nav generation without having to specify the docs_dir key

Add support for docs_dir mkdocs.yml config

Feature Suggestion

mkdocs-monorepo-plugin should understand and support the docs_dir config in included mkdocs.yml files.

Possible Implementation

We have access to the config of the included mkdocs.yml in the parser, which means we can get the docs_dir.

Context

By supporting docs_dir in referenced mkdocs.yml files, we open up a couple of nice use-cases:

  • The possibility to reference a sibling mkdocs.yml configuration which contains subsets of documentation from submodules within a monorepo (while the submodules themselves have their own, complete mkdocs.yml files).
  • The possibility for simpler submodule topologies with simpler documentation needs (e.g. submodules which only need a single README.md, which is more conveniently kept at the submodule's root directory, rather than in a docs sub-folder)

Naturally, other use-cases would be possible as well.

Original Report

Hi i was wondering if it would be possible to allow for the use of docs_dir attribute in a mkdocs.yml config file

My issue is that we have a submodule that is used in many projects, and it has a lot of documentation. These many projects don't all need the full documentation from the submodule, but only a subset.
There for the idea was to create a mkdocs_submodule.yml in the root git repository that only includes the needed documentation.

This would allow us to build tailored documentation packages for each of our projects.

Error when trying to do mkdocs serve

Hi everyone!
I'm currently using the latest version released of the plugin (v1.0.4) and my mkdocs.yml file has this line inside the navigation part.

nav:
  - Home: index.md
  - API:
     - books_try1: '!include ./packages/cr_packages/cr-customer-booksuite/mkdocs.yml'
     - books_tr2: '*include ./packages/cr_packages/*/mkdocs.yml'

plugins:
  - monorepo
  - search:
      lang: en
  - mkdocstrings:

The problem is that is not working with any of the !include possibilities, I always get this same error:

INFO     -  Building documentation...
INFO     -  Cleaning site directory
INFO     -  The following pages exist in the docs directory, but are not included in the "nav"
            configuration:
              - keep_data_updated.md
              - workflow_deepdive.md
ERROR    -  Error reading page 'cr-customer-booksuite/index.md': 'NoneType' object has no
            attribute 'endswith'
Traceback (most recent call last):
  File "/opt/anaconda3/envs/c1wv2/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/__main__.py", line 181, in serve_command
    serve.serve(dev_addr=dev_addr, livereload=livereload, watch=watch, **kwargs)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/commands/serve.py", line 63, in serve
    config = builder()
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/commands/serve.py", line 58, in builder
    build(config, live_server=live_server, dirty=dirty)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/commands/build.py", line 292, in build
    _populate_page(file.page, config, files, dirty)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/commands/build.py", line 163, in _populate_page
    page = config['plugins'].run_event(
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs/plugins.py", line 102, in run_event
    result = method(item, **kwargs)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/plugin.py", line 71, in on_pre_page
    set_edit_url(config, page, self)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 105, in set_edit_url
    page.edit_url = edit_url.build()
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 98, in build
    if self.__has_repo():
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 85, in __has_repo
    page_config_file_yaml = self.__get_page_config_file_yaml()
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 82, in __get_page_config_file_yaml
    return self.__load_page_config_file(f)
  File "/opt/anaconda3/envs/c1wv2/lib/python3.8/site-packages/mkdocs_monorepo_plugin/edit_uri.py", line 68, in __load_page_config_file
    and not page_repo_url.endswith('/'):
AttributeError: 'NoneType' object has no attribute 'endswith'

I was reading some ways to address this problem, and found this two issues: #77 and backstage/mkdocs-techdocs-core#62

I think they are related to this error, but other than installing the v1.0.0 version, does anyone know a different way to fix this?

Thanks a lot in advance!

Is the sample broken ?

tried on windows 10.
It seems to search file on C drive... while the repo is cloned on G: drive...
As you can read in the log

  • Steps to reproduce (python 3.8.3)

pip install mkdocs-monorepo-plugin
mkdocs serve

G:\DXC\JET\mkdocs-monorepo-plugin\sample-docs (master -> origin)                                                    
λ mkdocs serve                                                                                                      
INFO    -  Building documentation...                                                                                
INFO    -  Cleaning site directory                                                                                  
ERROR   -  Error reading page 'versions\v1\changelog.md': 'C:\\Users\\LDELAP~1\\AppData\\Local\\Temp\\docs_f5_vyqpp\
\versions\\v1\\changelog.md'                                                                                        
Traceback (most recent call last):                                                                                  
  File "g:\applis\python383\lib\runpy.py", line 194, in _run_module_as_main                                         
    return _run_code(code, main_globals, None,                                                                      
  File "g:\applis\python383\lib\runpy.py", line 87, in _run_code                                                    
    exec(code, run_globals)                                                                                         
  File "G:\APPLIS\Python383\Scripts\mkdocs.exe\__main__.py", line 7, in <module>                                    
  File "g:\applis\python383\lib\site-packages\click\core.py", line 829, in __call__                                 
    return self.main(*args, **kwargs)                                                                               
  File "g:\applis\python383\lib\site-packages\click\core.py", line 782, in main                                     
    rv = self.invoke(ctx)                                                                                           
  File "g:\applis\python383\lib\site-packages\click\core.py", line 1259, in invoke                                  
    return _process_result(sub_ctx.command.invoke(sub_ctx))                                                         
  File "g:\applis\python383\lib\site-packages\click\core.py", line 1066, in invoke                                  
    return ctx.invoke(self.callback, **ctx.params)                                                                  
  File "g:\applis\python383\lib\site-packages\click\core.py", line 610, in invoke                                   
    return callback(*args, **kwargs)                                                                                
  File "g:\applis\python383\lib\site-packages\mkdocs\__main__.py", line 133, in serve_command                       
    serve.serve(                                                                                                    
  File "g:\applis\python383\lib\site-packages\mkdocs\commands\serve.py", line 141, in serve                         
    config = builder()                                                                                              
  File "g:\applis\python383\lib\site-packages\mkdocs\commands\serve.py", line 136, in builder                       
    build(config, live_server=live_server, dirty=dirty)                                                             
  File "g:\applis\python383\lib\site-packages\mkdocs\commands\build.py", line 271, in build                         
    _populate_page(file.page, config, files, dirty)                                                                 
  File "g:\applis\python383\lib\site-packages\mkdocs\commands\build.py", line 160, in _populate_page                
    page = config['plugins'].run_event(                                                                             
  File "g:\applis\python383\lib\site-packages\mkdocs\plugins.py", line 94, in run_event                             
    result = method(item, **kwargs)                                                                                 
  File "g:\applis\python383\lib\site-packages\mkdocs_monorepo_plugin\plugin.py", line 62, in on_pre_page            
    page.file.abs_src_path = self.files_source_dir[page.file.abs_src_path]                                          
KeyError: 'C:\\Users\\LDELAP~1\\AppData\\Local\\Temp\\docs_f5_vyqpp\\versions\\v1\\changelog.md'                    
                                                                                                                    

BUG: Edit URI of !included mkdocs.yml not respected when building pages

Expected Behaviour

When creating documentation with the monorepo plugin I expect to be able to include sub-documentation and have the edit link on the final page be correct.

Current Behavior

When I load a page generated from the sub-documentation the ✏️ Edit link is incorrect, taking me to a 404.

Steps to Reproduce

I've added a sample docs folder that reproduces this issue.

  1. Checkout to this branch
  2. cd __tests__/integration/fixtures/bug-include-path-edit-uri
  3. npx @techdocs/cli build
  4. Inspect the index.html and test/index.html generated in the site folder

The top level docs is correct, the edit url generated is: https://github.com/egnwd/mkdocs-monorepo-plugin/edit/bug-edit-uri/__tests__/integration/fixtures/bug-include-path-edit-uri/docs/index.md
The sub-docs is incorrect, the edit url generated is: https://github.com/egnwd/mkdocs-monorepo-plugin/edit/bug-edit-uri/__tests__/integration/fixtures/bug-include-path-edit-uri/docs/test/index.md

Note the ending should be .../api/docs/index.md but is .../docs/test/index.md which is its location once the merger has aggregated the folders and named them after the site_name.

Add possibility to overwrite repo_url and edit_uri for includes

Thanks for this plugin, it's great.

We like to use the edit button to jump directly to our git repo in edit mode.

However when using !include the path doesn't match any longer the one which is specified in edit_uri in the main mkdocs.yml.

It would be great to have the possibility to add repo_url and edit_uri for the included dirs so that the correct git repo and edit_uri links are generated.

Is additional configuration required in order to use Git Submodules?

I have a situation where I am able to execute python -m mkdocs serve and have a monorepo documentation site run with no problem (even with a fresh clone).

However, when it comes to execution in backstage, I get something like:
[mkdocs-monorepo] The file path /tmp/backstage-0tvdBh/my-other-repo-submodule/mkdocs.yml does not exist, is not valid YAML, or does not contain a valid 'site_name' and 'nav' keys.

My guess right now is that the clone of the repository isn't including --recurse-submodules and therefor has no content, but I am also unsure on where I should look for this or enable this. Do I have to modify something else in backstage to properly support Git Submodules?

Merge subdirectories into the same tree?

I have a repo with multiple directories with individual READMEs and mkdocs.yml e.g.:

|-core
   |-docs
      -mkdocs.yml
      |-README.md
site_name: core
nav: 
  - Networking: README.md

I have included them in my nav so that it looks like:

nav:
  - Overview: 'README.md'
  - Implementation: 'IMPLEMENTATION.md'
  - Infrastructure: 
    - Networking: '!include ./core/mkdocs.yml'
    - Metadata: '!include ./metadata/mkdocs.yml'
    - Extraction: '!include ./pipelines/mkdocs.yml'
    - Glue: '!include ./glue_database/mkdocs.yml'

This creates the following output:
image

I was wondering if there was a way of merging contents into a single output tree so that the individual headers are not duplicated e.g.:

Infrastructure
  - Networking
  - Metadata
  - Extraction
  - Glue

Running a build with this plugin includes a pile of files from /System/Volumes/Data/private

I'm running macOS Big Sur.

my mkdocs.yml looks like this:

site_name: Garden Docs

nav:
  - Garden: garden/README.md
  - Garden Guide:
      - Setup: garden/00-setup.md
      - Remote Deployment: garden/01-remote-deployment.md
      - Remote Debugging: garden/02-remote-debugging.md
      - Adding A Module: garden/03-adding-a-module.md
      - Working With Garden: garden/04-working-with-garden.md
      - Known Issues: garden/05-known-issues.md
      - Cheatsheet: garden/06-cheatsheet.md
      - Compose To Garden Translation: garden/07-compose-to-garden-translation.md
      - Configuring Cluster: garden/08-configuring-cluster.md
      - Garden Ms Scaffold Explained: garden/09-garden-ms-scaffold-explained.md
      - Hot Reload: garden/10-hot-reload.md
  - Config: config.md
  - Docker Compose: docker-compose.md
  - Local Dev: local-dev.md
  - Packages: packages.md
  - Service Checklist: service-checklist.md

plugins:
  - techdocs-core

my filesystem tree looks like this:

.
├── docs
│   ├── config.md
│   ├── docker-compose.md
│   ├── garden
│   │   ├── 00-setup.md
│   │   ├── 01-remote-deployment.md
│   │   ├── 02-remote-debugging.md
│   │   ├── 03-adding-a-module.md
│   │   ├── 04-working-with-garden.md
│   │   ├── 05-known-issues.md
│   │   ├── 06-cheatsheet.md
│   │   ├── 07-compose-to-garden-translation.md
│   │   ├── 08-configuring-cluster.md
│   │   ├── 09-garden-ms-scaffold-explained.md
│   │   ├── 10-hot-reload.md
│   │   └── README.md
│   ├── local-dev.md
│   ├── packages.md
│   └── service-checklist.md
└── mkdocs.yml

upon building the docs with mkdocs build I get a lot of extraneous files

ls site
1E14906B-48F0-438B-B9F7-08FACA104585-lockscreen.png UpdateRingSettings.json                             local-dev
3CC215AE-598C-438D-B546-9BC231A6E374                assets                                              mat-debug-6273.log
3EA6F623-B3B8-4102-9EE3-CAB246C6AA2C                com.apple.Music                                     mat-debug-7205.log
404.html                                            com.apple.Safari                                    model.lock
5e84410f27304d289f168a76d51b240a.db                 com.apple.stocks.widget                             packages
5e84410f27304d289f168a76d51b240a.db-shm             com.microsoft.Outlook                               search
5e84410f27304d289f168a76d51b240a.db-wal             com.microsoft.teams Crashes                         service-checklist
5e84410f27304d289f168a76d51b240a.db.ses             config                                              sitemap.xml
ElixirSublime.log                                   docker-compose                                      sitemap.xml.gz
GitGutter.501                                       garden                                              techdocs_metadata.json
OneDriveVersion.xml                                 lghub Crashes                                       v8-compile-cache-501
TelemetryUploadFilecom.microsoft.autoupdate.fba.txt lghub_agent_instance_lock                           xcrun_db

I have somewhat isolated it to something between the tech docs plugin and this one

Workaround Limitations

Documentation says "site_name must adhere follow the regular expression: ^[a-zA-Z0-9_-/]+$"

My problem with that is that if you also want to single-build the repos you end up with a ugly site_name in the frontend. I wonder if you can introduce a new property like submodule_alias to work around that issue.

You may also autogenerate the machine name (lowercase, replace spaces and strip out special chars) and allow override via custom property. It would improve the "works out of the box" experience and you don't squat site_name prop.

https://github.com/spotify/mkdocs-monorepo-plugin/blob/a252e28a7129010e5e1db05efa08bade3ebb722c/mkdocs_monorepo_plugin/parser.py#L150

https://spotify.github.io/mkdocs-monorepo-plugin/limitations/

Error when running

I tried to add the plugin to mkdocs-material and locally. I get an error on live reaload changes:

[E 191011 14:40:27 ioloop:909] Exception in callback <bound method LiveReloadHandler.poll_tasks of <class 'livereload.handlers.LiveReloadHandler'>>
    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/site-packages/tornado-6.0.3-py3.6-linux-x86_64.egg/tornado/ioloop.py", line 907, in _run
        return self.callback()
      File "/usr/local/lib/python3.6/site-packages/livereload-2.6.1-py3.6.egg/livereload/handlers.py", line 69, in poll_tasks
        filepath, delay = cls.watcher.examine()
      File "/usr/local/lib/python3.6/site-packages/livereload-2.6.1-py3.6.egg/livereload/watcher.py", line 94, in examine
        if self.is_changed(path, item['ignore']):
      File "/usr/local/lib/python3.6/site-packages/livereload-2.6.1-py3.6.egg/livereload/watcher.py", line 121, in is_changed
        if os.path.isfile(path):
      File "/usr/local/lib/python3.6/genericpath.py", line 30, in isfile
        st = os.stat(path)
    TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType

Sorry in advance if my question is be stupid. I'm not a python developer.

Question about Python dependency resolution when using the monrepo plugin with mkdocstrings plugin

Hello there,

We make use of a plugin called mkdocstrings to generate documentation for the source code. This plugin loads the different Python libraries mentioned in the source code during the documentation generation process. As a result of this, there are Python dependency resolution issues that we encounter when using the monrepo plugin in a root repository . If the mkdocs.yaml file in the root repository references multiple mkdocs.yaml files from different repositories, we run into dependency resolution errors as there are conflicting dependency requirements in the different repositories.

The code in each of the different repositories uses different versions of the same Python module. Hence, the issue.
I am wondering that this must be an issue at a lot of organizations.
How is this overcome elsewhere?

To overcome this, we were thinking that the docs folder in each of the different repositories should be processed independently and the output of the mkdocs build command should be copied to some place in the root repository and then have mkdocs somehow assemble the documentation. I am not sure if this is even possible. If someone has already done this, please respond back.

Thanks,
Kiran Hegde

Search disabled ?

I just tried converting my documentation to use this plugin and the Search modal disappeared. Is search supported ?

Thanks !

Warnings during build ("duplicate filename")

Thanks for the great plugin!

This is maybe just a question, not an issue, but here goes:

We have a lot of "sub-documentations", and during build of the root mkdocs.yml, we get a lot of warnings during build:

WARNING -  Duplicate filename: 'protocol.md' exists at both '/var/folders/s5/d5n7fmn927q89ky03v4tbz_00000gn/T/docs_vokpwu1o/something/protocol.md' and '/var/folders/s5/d5n7fmn927q89ky03v4tbz_00000gn/T/docs_vokpwu1o/something/protocol.md'
WARNING -  Duplicate filename: 'engine.md' exists at both '/var/folders/s5/d5n7fmn927q89ky03v4tbz_00000gn/T/docs_vokpwu1o/xx/engine.md' and '/var/folders/s5/d5n7fmn927q89ky03v4tbz_00000gn/T/docs_vokpwu1o/xx/engine.md'

Is this a known thing, or do we maybe have a configuration error? I cannot see what is immediately wrong about reusing a file name as long as they are in different directories.

Include docs from outside main directory

Lets say I have multiple mkdocs projects on multiple disks. How would I use monorepo to include them in one site.
bit like this,

├───A
│   └───src
│       │   mkdocs.yml
│       │
│       └───docs
├───B
│   └───src
│       │   mkdocs.yml
│       │
│       └───docs
└───C
    └───monorepo
            mkdocs.yml

I the monorepo's yml file I have tried

nav:
  - C:
    - A: '!include A:/src/mkdocs.yml'
    - B: '!include B:/src/mkdocs.yml'

Obviously, both A and B are not in the monorepo root so I have this error

[mkdocs-monorepo] The mkdocs file A:\src\mkdocs.yml is outside of the current directory. Please move the file and try again.

I can't have them all in the same directory. Can we have a config option that allows out of directory includes? I cant use https://github.com/wilhelmer/mkdocs-multirepo because A, B and C are not publicly facing git repos.

Support dynamic navigation in main and subfolder mkdocs.yml files

While this plugin is awesome for monorepos, it does introduce the burden of having to define the complete navigation structure manually.

It would be great if functionality similar to mkdocs-awesome-pages-plugin could be included. The point would be to allow navigation structures to be partially defined (i.e. to add !include directives) yet still end up with a complete navigation tree.

As for why? Well, it would allow team members to add new docs without having to also update and maintain the mkdocs.yml file.

The github pages link for this repo results in a 404

It seems like the mkdocs-monorepo-plugin repo has moved from https://github.com/spotify/mkdocs-monorepo-plugin to https://github.com/backstage/mkdocs-monorepo-plugin and as such the github pages link it now broken and results in a 404.

It's a known issue that when a repo is transferred between organizations and users the github repos automatically redirect but the github pages do not.

Please update the old link (https://spotify.github.io/mkdocs-monorepo-plugin/) to the new link (https://backstage.github.io/mkdocs-monorepo-plugin/)

Can Monorepo plugin execute other plugins inside respective subrepos?

Hello everyone,

my most useful plugins so far mkdocstrings, and macros do not work anymore whithin the subrepo when it is pulled and built by monorepo.

monorepo mkdocs.yml:

plugins:
   - monorepo

subrepo mkdocs.yml:

plugins:
   - macros
   - mkdocstrings

Added to plugins section under mkdocs.yml in the monorepo it would work with a lot of rewriting paths. But as the docs live close to the code in the respective subrepos I want the developers to write docstrings and macros in their own repo's .md pages and see them in their own (local) mkdocs build.

Do I get something wrong about monorepo or is there a possibility to realize this?

Unable to use includes

On child projects we use includes for files that need to be at project root, like README.md or CHANGELOG.md and this is achieved using

<!-- docs/changelog.md -->
{!../CHANGELOG.md!}
# child mkdocs.yml file
plugins:
  - markdown_include.include:
      base_path: docs

While this works when building docs of each child-site, it does not work with monorepo plugin.

I mention that our initial attempt was to use symlinks from docs/ to parent but that does not work with mkdocs either, being forced to use the include method. Also creating symlinks from root to docs/ folder does not work because github does not display these markdown files correctly.

Related: cmacmackin/markdown-include#41

Respect Gitlinks per Attached Repository

Hello dear community, in e.g. mkdocs-material there is nice feature: https://squidfunk.github.io/mkdocs-material/setup/adding-a-git-repository/#adding-a-git-repository

By simple config in yaml file:

repo_name: Trolololo
repo_url: https://somehost.com/Trololo
edit_uri: "edit/master/docs/"

will enable this:
grafik
By clicking you are jumping into the Repositroy to exact file.

When I use monorepo no links will be provided.

Please respect config per attached repository.

Incompatibility with timvink/mkdocs-git-revision-date-localized-plugin

Hello,

I was trying to use the MkDocs plugin timvink/mkdocs-git-revision-date-localized-plugin in my project but it always fails with:

$ mkdocs build
INFO    -  Cleaning site directory 
INFO    -  Building documentation to directory: /home/prcr/Codacy/git/docs/site 
ERROR   -  Unable to read git logs of '/tmp/docs_kvh_ua8a/index.md'. To ignore this error, set option 'ignoring_missing_git: true'
ERROR   -  Error reading page 'index.md': Cmd('git') failed due to: exit code(128)
  cmdline: git log --date=short --format=%at -n 1 /tmp/docs_kvh_ua8a/index.md
  stderr: 'fatal: /tmp/docs_kvh_ua8a/index.md: '/tmp/docs_kvh_ua8a/index.md' is outside repository' 
[...]

I was able to pinpoint the issue to the fact that I'm using mkdocs-monorepo-plugin as well. It seems that the plugin copies the *.md files to a temporary directory before building them, and this way the other plugin cannot use git log to find out the last updated date of the Markdown files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.