Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bumped react-script, seems to fix install and run issues #32

Merged
merged 14 commits into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: CI

on:
push:
branches:
- "master"
pull_request:
branches:
- "master"

jobs:
build-templates:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version:
# For details, see: https://nodejs.dev/en/about/releases/
# Maintance LTS. End Of Life: 2023-04-30
- 14.x
# Maintance LTS. End Of Life: 2023-09-11
- 16.x
# The following versions are not supported as
# they require react-script 5 which requires changes in
# streamlit-component-lib package.
# For details, see:
# https://github.com/streamlit/streamlit/pull/6584
# # Active LTS. End Of Life: 2025-04-30
# - 18.x
# # Current version
# - 19.x
cwd:
- ./template
- ./template-reactless

name: Templates / node-version=${{ matrix.node-version }} / cwd=${{ matrix.cwd }}

steps:
- uses: actions/checkout@v3
with:
persist-credentials: false

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Install node dependencies
working-directory: ${{ matrix.cwd }}/my_component/frontend
run: npm install

- name: Build frontend code
working-directory: ${{ matrix.cwd }}//my_component/frontend
run: npm run build

build-examples:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
node-version:
# For details, see: https://nodejs.dev/en/about/releases/
# Maintance LTS. End Of Life: 2023-04-30
- 14.x
# Maintance LTS. End Of Life: 2023-09-11
- 16.x
# The following versions are not supported as
# they require react-script 5 which requires changes in
# streamlit-component-lib package.
# For details, see:
# https://github.com/streamlit/streamlit/pull/6584
# # Active LTS. End Of Life: 2025-04-30
# - 18.x
# # Current version
# - 19.x

name: Examples / node-version=${{ matrix.node-version }}

steps:
- uses: actions/checkout@v3
with:
persist-credentials: false

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}

- name: Check dependencies
run: ./dev.py examples-check-deps

- name: Install node dependencies
run: ./dev.py examples-npm-install

- name: Build frontend code
run: ./dev.py examples-npm-build
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ node_modules/
coverage/

# Lockfiles
yarn.lock
package-lock.json
template/**/yarn.lock
template/**/package-lock.json
template-reactless/**/yarn.lock
template-reactless/**/package-lock.json

########################################################################
# JetBrains
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ These templates are provided by the community. If you run into any issues, pleas
- [streamlit-component-template-vue](https://github.com/andfanilo/streamlit-component-template-vue) - [@andfanilo](https://github.com/andfanilo)
- [streamlit-component-template-react-hooks](https://github.com/whitphx/streamlit-component-template-react-hooks) - [@whitphx](https://github.com/whitphx)

## Contributing

If you want to contribute to this project, `./dev.py` script will be helpful for you. For details, run `./dev.py --help`.

## More Information

* [Streamlit Components documentation](https://docs.streamlit.io/library/components)
Expand Down
103 changes: 103 additions & 0 deletions dev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
A tool to support the maintenance of templates and examples in this repository.
Something like a Makefile but written in Python for easier maintenance.

To list the available commands, run ./dev.py --help.
"""
import argparse

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, if you're looking for other make alternatives, I really like https://taskfile.dev/

from glob import glob
import shlex
import subprocess
from pathlib import Path
import json
import sys

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a short docstring explaining the purpose of this script? Is it something we expect users to use, or is it just for Streamlit devs? (Should we include info about it in the repo's README?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Added.

THIS_DIRECTORY = Path(__file__).parent.absolute()
EXAMPLE_DIRECTORIES = (d for d in (THIS_DIRECTORY / 'examples').iterdir() if d.is_dir())

# Utilities function
def run_verbose(cmd_args, *args, **kwargs):
kwargs.setdefault("check", True)
cwd = kwargs.get('cwd')
message_suffix = f" [CWD: {Path(cwd).relative_to(THIS_DIRECTORY)}]" if cwd else ''

print(f"$ {shlex.join(cmd_args)}{message_suffix}", flush=True)
subprocess.run(cmd_args, *args, **kwargs)


# Commands
def cmd_example_npm_install(args):
""""Install all node dependencies for all examples"""
for example_dir in EXAMPLE_DIRECTORIES:
run_verbose(["npm", "install"], cwd=str(example_dir / "frontend"))


def cmd_example_npm_build(args):
""""Build javascript code for all examples"""
for example_dir in EXAMPLE_DIRECTORIES:
run_verbose(["npm", "run", "build"], cwd=str(example_dir / "frontend"))

def check_deps(template_package_json, current_package_json):
return (
check_deps_section(template_package_json, current_package_json, 'dependencies') +
check_deps_section(template_package_json, current_package_json, 'devDependencies')
)

def check_deps_section(template_package_json, current_package_json, section_name):
current_package_deps = current_package_json.get(section_name, dict())
template_package_deps = template_package_json.get(section_name, dict())
errors = []

for k, v in template_package_deps.items():
if k not in current_package_deps:
errors.append(f'Missing [{k}:{v}] in {section_name!r} section')
continue
current_version = current_package_deps[k]
if current_version != v:
errors.append(f'Invalid version of {k!r}. Expected: {v!r}. Current: {current_version!r}')
return errors


def cmd_example_check_deps(args):
"""Checks that dependencies of examples match the template"""
tempalte_deps = json.loads((THIS_DIRECTORY / "template" / "my_component" / "frontend" / "package.json").read_text())
examples_package_jsons = sorted(d / "frontend"/ "package.json" for d in EXAMPLE_DIRECTORIES)
exit_code = 0
for examples_package_json in examples_package_jsons:
example_deps = json.loads(examples_package_json.read_text())
errors = check_deps(tempalte_deps, example_deps)
if errors:
print(f"Found erorr in {examples_package_json.relative_to(THIS_DIRECTORY)!s}")
print("\n".join(errors))
print()
exit_code = 1
if exit_code == 0:
print("No errors")

sys.exit(exit_code)

COMMMANDS = {
"examples-npm-install": cmd_example_npm_install,
"examples-npm-build": cmd_example_npm_build,
"examples-check-deps": cmd_example_check_deps,
}

# Parser
def get_parser():
parser = argparse.ArgumentParser(prog=__file__, description=__doc__)
subparsers = parser.add_subparsers(dest="subcommand", metavar="COMMAND")
subparsers.required = True
for commmand_name, command_fn in COMMMANDS.items():
subparsers.add_parser(commmand_name, help=command_fn.__doc__).set_defaults(func=command_fn)
return parser


# Main function
def main():
parser = get_parser()
args = parser.parse_args()
args.func(args)

if __name__ == "__main__":
main()
Loading