Skip to content

Commit

Permalink
feat #31 ci build 客户端
Browse files Browse the repository at this point in the history
  • Loading branch information
zy7y committed Apr 27, 2024
1 parent 1556e3a commit 6eb987f
Show file tree
Hide file tree
Showing 11 changed files with 386 additions and 109 deletions.
62 changes: 59 additions & 3 deletions .github/workflows/build.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,75 @@
import platform
import subprocess

import yapf_third_party
from PyInstaller import __main__ as pyi


def gen_client_py():
code = """
import random
import socket
import threading
from dfs_generate.server import app
def get_unused_port():
while True:
port = random.randint(1024, 65535) # 端口范围一般为1024-65535
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.bind(("localhost", port))
sock.close()
return port
except OSError:
pass
import webview
def desktop_client():
port = get_unused_port()
t = threading.Thread(target=app.run, kwargs={"port": port})
t.daemon = True
t.start()
webview.create_window("DFS代码生成", f"http://127.0.0.1:{port}")
webview.start()
if __name__ == '__main__':
desktop_client()
"""
with open("dfs_generate/client.py", "w", encoding="utf-8") as f:
f.write(code)


gen_client_py()


params = [
"--windowed",
"--onefile",
"--add-data",
"static:static",
"web/dist:web/dist",
"--add-data",
f'{yapf_third_party.__file__.replace("__init__.py", "")}:yapf_third_party',
"--clean",
"--noconfirm",
"--name=client",
"server.py",
"dfs_generate/client.py",
]


pyi.run(params)


# 如果是macos,则压缩打包后的目录
if platform.system() == "Darwin":
cmds = ["zip", "-r", "dist/client.zip", "dist/"]
subprocess.call(cmds)
rm_cmds = ["rm", "-rf", "dist/client.app"]
subprocess.call(rm_cmds)
# 删除空目录
rm_cmds = ["rm", "-rf", "dist/client"]
subprocess.call(rm_cmds)
44 changes: 44 additions & 0 deletions .github/workflows/build_client.yml
Original file line number Diff line number Diff line change
@@ -1 +1,45 @@
# 构建桌面端
name: build

on:
push:
branches:
- 25-todo
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ windows-latest, macos-latest ]
steps:
- name: Checkout代码
uses: actions/checkout@v3
- name: 设置Node.js环境
uses: actions/setup-node@v3
with:
node-version: 18.15
- name: 进入web目录
run: cd web
- name: 安装依赖
run: npm i
- name: 打包Node.js应用
run: npm run build
- uses: actions/checkout@v3
- name: Set up Python 3.11
uses: actions/setup-python@v3
with:
python-version: "3.11"
- name: Install dependencies
run: |
pip install -r requirements-build.txt
- name: Build executable
run: |
python .github/workflows/build.py
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: Setup
retention-days: 1
path: ./dist/*
100 changes: 0 additions & 100 deletions .github/workflows/release.yml

This file was deleted.

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,11 @@

<!-- CONTRIBUTORS_SECTION -->
<!-- /CONTRIBUTORS_SECTION -->
<details>
<summary>WeChat打赏</summary>

![wechat](docs/wechat.jpeg)

</details>


4 changes: 2 additions & 2 deletions dfs_generate/conversion.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from string import Template

from templates import (
from dfs_generate.templates import (
SQLMODEL_DAO,
TORTOISE_DAO,
RESPONSE_SCHEMA,
Expand All @@ -10,7 +10,7 @@
TORTOISE_ROUTER,
SQLMODEL_DB,
)
from tools import to_pascal, tran, to_snake
from dfs_generate.tools import to_pascal, tran, to_snake


def _pydantic_field(column, imports):
Expand Down
9 changes: 6 additions & 3 deletions dfs_generate/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@
import isort
from yapf.yapflib.yapf_api import FormatCode

from conversion import SQLModelConversion, TortoiseConversion
from tools import MySQLConf, MySQLHelper
from dfs_generate.conversion import SQLModelConversion, TortoiseConversion
from dfs_generate.tools import MySQLConf, MySQLHelper

app = bottle.Bottle()

CACHE: Dict[str, MySQLHelper] = {}

# 解决打包桌面程序static找不到的问题
static_file_abspath = os.path.join(os.path.dirname(__file__), "../web/dist")
static_file_abspath = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "web", "dist"
)
print(static_file_abspath)


@app.hook("before_request")
Expand Down
2 changes: 1 addition & 1 deletion dfs_generate/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import pymysql

from types_map import TYPES
from dfs_generate.types_map import TYPES


def tran(t, mode) -> dict:
Expand Down
Binary file added docs/wechat.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import pytest
from dfs_generate.client import get_unused_port, desktop_client


# 由于get_unused_port函数依赖于随机性和系统状态,我们倾向于对socket操作进行mock
@pytest.mark.parametrize("mocked_port", [12345])
def test_get_unused_port(mocker, mocked_port):
# Mocking the socket operations
mock_socket = mocker.patch("dfs_generate.client.socket.socket")
mock_socket.bind.return_value = None
mock_socket.close.return_value = None

# To ensure we control the behavior of randint for predictable testing
mock_randint = mocker.patch("dfs_generate.client.random.randint")
mock_randint.return_value = mocked_port

# Test the function
port = get_unused_port()
assert port == mocked_port
mock_socket.bind.assert_called_once_with(("localhost", mocked_port))
mock_socket.close.assert_called_once()


@pytest.fixture
def mock_app_run(mocker):
"""Fixture to mock app.run method."""
mock_run = mocker.patch("dfs_generate.server.app.run")
yield mock_run


@pytest.fixture
def mock_webview(mocker):
"""Fixture to mock webview functions."""
mock_create_window = mocker.patch("webview.create_window")
mock_start = mocker.patch("webview.start")
yield mock_create_window, mock_start


def test_desktop_client(mock_app_run, mock_webview):
"""Test the desktop_client function."""
# Since get_unused_port is mocked in test_get_unused_port, we can assume it works.
# Here we focus on verifying app.run and webview interactions.
desktop_client()

mock_app_run.assert_called_once_with(
port=12345
) # Assuming 12345 is a typical port used in tests
create_window, start = mock_webview
create_window.assert_called_once_with("DFS代码生成", "http://127.0.0.1:12345")
start.assert_called_once()
Loading

0 comments on commit 6eb987f

Please sign in to comment.