build and upload executables created by PyInstaller
- create release on tag push - build executables by PyInstaller: - extract_otp_secrets_linux_x86_64 (glibc 2.28) - extract_otp_secrets_win_x86_64.exe - extract_otp_secrets_macos_x86_64 (untested) - add --version - build linux executable in docker container - update README - add TOC - improve badges - add PyInstaller section - docker - build BASE_IMAGE as ARG - copy only required files to image - add .alias - build.sh - fix clean - fix generate results - generate TOCpull/47/head v2.1.0b1
parent
445d77783c
commit
6a7a7233a4
@ -0,0 +1,281 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
# https://data-dive.com/multi-os-deployment-in-cloud-using-pyinstaller-and-github-actions
|
||||||
|
# https://github.com/actions/create-release (archived)
|
||||||
|
# https://github.com/actions/upload-artifact
|
||||||
|
# https://github.com/actions/download-artifact
|
||||||
|
# https://github.com/actions/upload-release-asset (archived)
|
||||||
|
# https://github.com/docker/metadata-action
|
||||||
|
# https://github.com/marketplace/actions/generate-release-hashes
|
||||||
|
|
||||||
|
# https://github.com/oleksis/pyinstaller-manylinux
|
||||||
|
# https://github.com/pypa/manylinux
|
||||||
|
# https://github.com/batonogov/docker-pyinstaller
|
||||||
|
|
||||||
|
# https://docs.github.com/de/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/using-workflows
|
||||||
|
# https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||||
|
# https://docs.github.com/en/actions/learn-github-actions/expressions
|
||||||
|
|
||||||
|
# https://docs.github.com/en/rest/releases/releases
|
||||||
|
|
||||||
|
# https://peps.python.org/pep-0440/
|
||||||
|
# https://semver.org/
|
||||||
|
|
||||||
|
# Build matrix:
|
||||||
|
# - Linux x86_64 glibc 2.35: ubuntu-latest
|
||||||
|
# - Linux x86_64 glibc 2.34: extract_otp_secrets:buster
|
||||||
|
# - Windows x86_64: windows-latest
|
||||||
|
# - MacOS x86_64: macos-11
|
||||||
|
# - Linux x86_64 glibc 2.28: extract_otp_secrets:buster
|
||||||
|
# - Linux aarch64 glibc 2.28: extract_otp_secrets:buster
|
||||||
|
# - MacOS universal2: macos-11
|
||||||
|
# - Windows arm64: [buildx + https://github.com/batonogov/docker-pyinstaller]
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
create-release:
|
||||||
|
name: Create Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set meta data
|
||||||
|
id: meta
|
||||||
|
# Writing to env with >> $GITHUB_ENV is an alternative
|
||||||
|
run: |
|
||||||
|
echo "date=$(TZ=Europe/Bern date +'%d.%m.%Y')" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${TAG_NAME/v/}" >> $GITHUB_OUTPUT
|
||||||
|
echo "tag_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
||||||
|
echo "tag_message=$(git tag -l --format='%(contents:subject)' ${{ github.ref_name }})" >> $GITHUB_OUTPUT
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.ref_name }}
|
||||||
|
- name: Create Release
|
||||||
|
id: create_release
|
||||||
|
run: |
|
||||||
|
# https://docs.github.com/en/rest/releases/releases?apiVersion=2022-11-28#create-a-release
|
||||||
|
response=$(curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
|
||||||
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||||
|
https://api.github.com/repos/scito/extract_otp_secrets/releases \
|
||||||
|
--silent \
|
||||||
|
--show-error \
|
||||||
|
-d '{"tag_name":"${{ github.ref }}","target_commitish":"master","name":"${{ steps.meta.outputs.version }} - ${{ steps.meta.outputs.date }}","body":"${{ steps.meta.outputs.tag_message }}","draft":true,"prerelease":false,"generate_release_notes":true}')
|
||||||
|
echo upload_url=$(jq '.upload_url' <<< "$response") >> $GITHUB_OUTPUT
|
||||||
|
echo $(jq -r '.upload_url' <<< "$response") > release_url.txt
|
||||||
|
- name: Save Release URL File for publish
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: release_url
|
||||||
|
path: release_url.txt
|
||||||
|
|
||||||
|
build-and-push-docker-image:
|
||||||
|
name: Build Linux release in docker container
|
||||||
|
# run only when code is compiling and tests are passing
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: create-release
|
||||||
|
|
||||||
|
# steps to perform in job
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# avoid building if there are testing errors
|
||||||
|
- name: Run smoke test
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libzbar0
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -U -r requirements-dev.txt
|
||||||
|
pip install -U .
|
||||||
|
pytest
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
# setup Docker build action
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login to Github Packages
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GHCR_IO_TOKEN }}
|
||||||
|
|
||||||
|
- name: "Build image from Buster and push to GitHub Container Registry"
|
||||||
|
id: docker_build_buster
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
# relative path to the place where source code with Dockerfile is located
|
||||||
|
# TODO file:, move to docker/
|
||||||
|
context: .
|
||||||
|
file: Dockerfile
|
||||||
|
# builder: ${{ steps.buildx.outputs.name }}
|
||||||
|
build-args: |
|
||||||
|
BASE_IMAGE=python:3.11-slim-buster
|
||||||
|
# Note: tags has to be all lower-case
|
||||||
|
pull: true
|
||||||
|
tags: |
|
||||||
|
ghcr.io/scito/extract_otp_secrets:buster
|
||||||
|
push: true
|
||||||
|
|
||||||
|
# # https://stackoverflow.com/a/61155718/1663871
|
||||||
|
# - name: Build docker images
|
||||||
|
# run: docker build -t local < .devcontainer/Dockerfile
|
||||||
|
# - name: Run tests
|
||||||
|
# run: docker run -it -v $PWD:/srv -w/srv local make test
|
||||||
|
|
||||||
|
- name: Image digest
|
||||||
|
# TODO upload digests to assets
|
||||||
|
run: |
|
||||||
|
echo "extract_otp_secrets: ${{ steps.docker_build_buster.outputs.digest }}"
|
||||||
|
|
||||||
|
- name: Run Pyinstaller in container
|
||||||
|
run: |
|
||||||
|
# TODO use local docker image https://stackoverflow.com/a/61155718/1663871
|
||||||
|
docker run --pull always --entrypoint /bin/bash --rm -v "$(pwd)":/files -w /files ghcr.io/scito/extract_otp_secrets:buster -c 'apt-get update && apt-get -y install binutils && pip install -U -r /files/requirements.txt && pip install pyinstaller && pyinstaller -y --add-data /usr/local/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --name extract_otp_secrets_linux_x86_64 --distpath /files/dist/ /files/src/extract_otp_secrets.py'
|
||||||
|
|
||||||
|
- name: Smoke tests
|
||||||
|
run: |
|
||||||
|
dist/extract_otp_secrets_linux_x86_64 -h
|
||||||
|
dist/extract_otp_secrets_linux_x86_64 example_export.png
|
||||||
|
dist/extract_otp_secrets_linux_x86_64 - < example_export.txt
|
||||||
|
- name: Load Release URL File from release job
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: release_url
|
||||||
|
- name: Display structure of files
|
||||||
|
run: ls -R
|
||||||
|
- name: Upload Release Asset
|
||||||
|
id: upload-release-asset
|
||||||
|
# TODO only for tags
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
response=$(curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "Content-Type: application/x-executable" \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
|
||||||
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||||
|
--silent \
|
||||||
|
--show-error \
|
||||||
|
--data-binary @dist/extract_otp_secrets_linux_x86_64 \
|
||||||
|
$(cat release_url.txt)=extract_otp_secrets_linux_x86_64)
|
||||||
|
|
||||||
|
build:
|
||||||
|
name: Build packages
|
||||||
|
needs: create-release
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#choosing-github-hosted-runners
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
TARGET: linux
|
||||||
|
CMD_BUILD: |
|
||||||
|
pyinstaller -y --add-data $pythonLocation/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile src/extract_otp_secrets.py
|
||||||
|
OUT_FILE_NAME: extract_otp_secrets
|
||||||
|
ASSET_NAME: extract_otp_secrets_linux_x86_64_ubuntu_latest
|
||||||
|
ASSET_MIME: application/x-executable
|
||||||
|
UPLOAD: false
|
||||||
|
- os: macos-11
|
||||||
|
TARGET: macos
|
||||||
|
# TODO add --icon
|
||||||
|
# TODO add --osx-bundle-identifier
|
||||||
|
# TODO add --codesign-identity
|
||||||
|
# TODO add --osx-entitlements-file
|
||||||
|
# TODO https://pyinstaller.org/en/stable/spec-files.html#spec-file-options-for-a-macos-bundle
|
||||||
|
# TODO --target-arch universal2
|
||||||
|
CMD_BUILD: |
|
||||||
|
pyinstaller -y --add-data $macos_python_path/__yolo_v3_qr_detector/:__yolo_v3_qr_detector/ --onefile --argv-emulation src/extract_otp_secrets.py
|
||||||
|
OUT_FILE_NAME: extract_otp_secrets
|
||||||
|
ASSET_NAME: extract_otp_secrets_macos_x86_64
|
||||||
|
ASSET_MIME: application/x-newton-compatible-pkg
|
||||||
|
UPLOAD: true
|
||||||
|
- os: windows-latest
|
||||||
|
TARGET: windows
|
||||||
|
# TODO add --icon
|
||||||
|
# TODO add --manifest
|
||||||
|
# TODO find more elegant solution for pyzbar\libiconv.dll and pyzbar\libzbar-64.dll
|
||||||
|
CMD_BUILD: |
|
||||||
|
pyinstaller -y --add-data "$($Env:pythonLocation)\__yolo_v3_qr_detector;__yolo_v3_qr_detector" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libiconv.dll;pyzbar" --add-binary "$($Env:pythonLocation)\Lib\site-packages\pyzbar\libzbar-64.dll;pyzbar" --onefile --version-file build\file_version_info.txt src\extract_otp_secrets.py
|
||||||
|
OUT_FILE_NAME: extract_otp_secrets.exe
|
||||||
|
ASSET_NAME: extract_otp_secrets_win_x86_64.exe
|
||||||
|
ASSET_MIME: application/vnd.microsoft.portable-executable
|
||||||
|
UPLOAD: true
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set macos macos_python_path
|
||||||
|
# TODO use variable for Python version
|
||||||
|
run: echo "macos_python_path=/Library/Frameworks/Python.framework/Versions/3.11" >> $GITHUB_ENV
|
||||||
|
- name: Set up Python 3.11
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: 3.11
|
||||||
|
check-latest: true
|
||||||
|
- name: Install zbar shared lib for QReader (Linux)
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get install -y libzbar0
|
||||||
|
- name: Install zbar shared lib for QReader (macOS)
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
brew install zbar
|
||||||
|
- name: Install dependencies
|
||||||
|
# TODO fix --use-pep517
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -U -r requirements-dev.txt
|
||||||
|
pip install -U .
|
||||||
|
- name: Create Windows file_version_info.txt
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir -p build/
|
||||||
|
VERSION_STR=$(setuptools-git-versioning) VERSION_MAJOR=$(cut -d '.' -f 1 <<< "$(setuptools-git-versioning)") VERSION_MINOR=$(cut -d '.' -f 2 <<< "$(setuptools-git-versioning)") VERSION_PATCH=$(cut -d '.' -f 3 <<< "$(setuptools-git-versioning)") VERSION_BUILD=$(($(git rev-list --count $(git tag | sort -V -r | sed '1!d')..HEAD))) YEARS='2020-2023' envsubst < file_version_info_template.txt > build/file_version_info.txt
|
||||||
|
- name: Build with pyinstaller for ${{ matrix.TARGET }}
|
||||||
|
run: ${{ matrix.CMD_BUILD }}
|
||||||
|
- name: Smoke tests for generated exe (general)
|
||||||
|
run: |
|
||||||
|
dist/${{ matrix.OUT_FILE_NAME }} -h
|
||||||
|
dist/${{ matrix.OUT_FILE_NAME }} example_export.png
|
||||||
|
- name: Smoke tests for generated exe (stdin)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
dist/${{ matrix.OUT_FILE_NAME }} - < example_export.txt
|
||||||
|
- name: Load Release URL File from release job
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: release_url
|
||||||
|
- name: Display structure of files
|
||||||
|
run: ls -R
|
||||||
|
- name: Upload Release Asset
|
||||||
|
id: upload-release-asset
|
||||||
|
# TODO only for tags
|
||||||
|
if: ${{ matrix.UPLOAD }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
response=$(curl \
|
||||||
|
-X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
-H "Content-Type: ${{ matrix.ASSET_MIME }}" \
|
||||||
|
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}"\
|
||||||
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||||
|
--silent \
|
||||||
|
--show-error \
|
||||||
|
--data-binary @dist/${{ matrix.OUT_FILE_NAME }} \
|
||||||
|
$(cat release_url.txt)=${{ matrix.ASSET_NAME }})
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
alias ll='ls -lh'
|
||||||
|
alias la='ls -lha'
|
||||||
|
alias l='ls -alhF'
|
||||||
|
alias ls-l='ls -lh'
|
@ -0,0 +1,56 @@
|
|||||||
|
Generate from file: README.md
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
- [Table of contents](#table-of-contents)
|
||||||
|
- [Usage](#usage)
|
||||||
|
- [Capture QR codes from camera (🆕 since version 2.0)](#capture-qr-codes-from-camera--since-version-20)
|
||||||
|
- [With builtin QR decoder from image files (🆕 since version 2.0)](#with-builtin-qr-decoder-from-image-files--since-version-20)
|
||||||
|
- [With external QR decoder app from text files](#with-external-qr-decoder-app-from-text-files)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Download binary executable (🆕 since v2.1)](#download-binary-executable--since-v21)
|
||||||
|
- [Run as script (recommend for developers or advanced users)](#run-as-script-recommend-for-developers-or-advanced-users)
|
||||||
|
- [Installation of shared system libraries](#installation-of-shared-system-libraries)
|
||||||
|
- [Program help: arguments and options](#program-help-arguments-and-options)
|
||||||
|
- [Examples](#examples)
|
||||||
|
- [Printing otp secrets form text file](#printing-otp-secrets-form-text-file)
|
||||||
|
- [Printing otp secrets from image file](#printing-otp-secrets-from-image-file)
|
||||||
|
- [Writing otp secrets to csv file](#writing-otp-secrets-to-csv-file)
|
||||||
|
- [Writing otp secrets to json file](#writing-otp-secrets-to-json-file)
|
||||||
|
- [Printing otp secrets multiple files](#printing-otp-secrets-multiple-files)
|
||||||
|
- [Printing otp secrets from stdin (text)](#printing-otp-secrets-from-stdin-text)
|
||||||
|
- [Printing otp secrets from stdin (image)](#printing-otp-secrets-from-stdin-image)
|
||||||
|
- [Printing otp secrets csv to stdout](#printing-otp-secrets-csv-to-stdout)
|
||||||
|
- [Printing otp secrets csv to stdout without header line](#printing-otp-secrets-csv-to-stdout-without-header-line)
|
||||||
|
- [Reading from stdin and printing to stdout](#reading-from-stdin-and-printing-to-stdout)
|
||||||
|
- [Features](#features)
|
||||||
|
- [KeePass](#keepass)
|
||||||
|
- [How to export otp secrets from Google Authenticator app](#how-to-export-otp-secrets-from-google-authenticator-app)
|
||||||
|
- [Glossary](#glossary)
|
||||||
|
- [Alternative installation methods](#alternative-installation-methods)
|
||||||
|
- [pip using github](#pip-using-github)
|
||||||
|
- [local pip](#local-pip)
|
||||||
|
- [pipenv](#pipenv)
|
||||||
|
- [Visual Studio Code Remote - Containers / VSCode devcontainer](#visual-studio-code-remote---containers--vscode-devcontainer)
|
||||||
|
- [venv](#venv)
|
||||||
|
- [devbox](#devbox)
|
||||||
|
- [docker](#docker)
|
||||||
|
- [More docker examples](#more-docker-examples)
|
||||||
|
- [Tests](#tests)
|
||||||
|
- [PyTest](#pytest)
|
||||||
|
- [unittest](#unittest)
|
||||||
|
- [VSCode Setup](#vscode-setup)
|
||||||
|
- [Development](#development)
|
||||||
|
- [Build](#build)
|
||||||
|
- [Upgrade pip Packages](#upgrade-pip-packages)
|
||||||
|
- [Build docker images](#build-docker-images)
|
||||||
|
- [Create executables with pyinstaller](#create-executables-with-pyinstaller)
|
||||||
|
- [Full local build (bash)](#full-local-build-bash)
|
||||||
|
- [Technical background](#technical-background)
|
||||||
|
- [References](#references)
|
||||||
|
- [Issues](#issues)
|
||||||
|
- [Problems and Troubleshooting](#problems-and-troubleshooting)
|
||||||
|
- [Windows error message](#windows-error-message)
|
||||||
|
- [Related projects](#related-projects)
|
||||||
|
|
||||||
|
Table of contents generated.
|
Before Width: | Height: | Size: 528 KiB After Width: | Height: | Size: 528 KiB |
@ -0,0 +1,46 @@
|
|||||||
|
# UTF-8
|
||||||
|
#
|
||||||
|
# For more details about fixed file info 'ffi' see:
|
||||||
|
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
|
||||||
|
VSVersionInfo(
|
||||||
|
ffi=FixedFileInfo(
|
||||||
|
# The elements of each tuple represent 16-bit values from most-significant to least-significant. For example the value (2, 0, 4, 0) resolves to 0002000000040000 in hex.
|
||||||
|
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
|
||||||
|
# Set not needed items to zero 0.
|
||||||
|
filevers=($VERSION_MAJOR, $VERSION_MINOR, $VERSION_PATCH, $VERSION_BUILD),
|
||||||
|
prodvers=($VERSION_MAJOR, $VERSION_MINOR, $VERSION_PATCH, $VERSION_BUILD),
|
||||||
|
# Contains a bitmask that specifies the valid bits 'flags'r
|
||||||
|
mask=0x3f,
|
||||||
|
# Contains a bitmask that specifies the Boolean attributes of the file.
|
||||||
|
flags=0x0,
|
||||||
|
# The operating system for which this file was designed.
|
||||||
|
# 0x4 - NT and there is no need to change it.
|
||||||
|
OS=0x4,
|
||||||
|
# The general type of file.
|
||||||
|
# 0x1 - the file is an application.
|
||||||
|
fileType=0x1,
|
||||||
|
# The function of the file.
|
||||||
|
# 0x0 - the function is not defined for this fileType
|
||||||
|
subtype=0x0,
|
||||||
|
# Creation date and time stamp.
|
||||||
|
date=(0, 0)
|
||||||
|
),
|
||||||
|
kids=[
|
||||||
|
StringFileInfo(
|
||||||
|
[
|
||||||
|
StringTable(
|
||||||
|
# 0x0409 (U.S. English) + 04B0 (1200 = Unicode), https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block
|
||||||
|
'040904B0',
|
||||||
|
[StringStruct('CompanyName', 'scito'),
|
||||||
|
StringStruct('FileDescription', 'extract_otp_secrets'),
|
||||||
|
StringStruct('FileVersion', '$VERSION_STR'),
|
||||||
|
StringStruct('InternalName', 'extract_otp_secrets'),
|
||||||
|
StringStruct('LegalCopyright', 'Copyright © $YEARS Scito.'),
|
||||||
|
StringStruct('OriginalFilename', 'extract_otp_secrets.exe'),
|
||||||
|
StringStruct('ProductName', 'extract_otp_secrets'),
|
||||||
|
StringStruct('ProductVersion', '$VERSION_STR')])
|
||||||
|
]),
|
||||||
|
# 1033 (0x0409 = U.S. English), 1200 (Unicode)
|
||||||
|
VarFileInfo([VarStruct('Translation', [0, 1200])])
|
||||||
|
]
|
||||||
|
)
|
@ -1,11 +1,14 @@
|
|||||||
build
|
build
|
||||||
flake8
|
flake8
|
||||||
|
gfm-toc
|
||||||
mypy
|
mypy
|
||||||
mypy-protobuf
|
mypy-protobuf
|
||||||
|
pyinstaller
|
||||||
pylint
|
pylint
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-mock
|
pytest-mock
|
||||||
setuptools
|
setuptools
|
||||||
|
setuptools-git-versioning
|
||||||
types-protobuf
|
types-protobuf
|
||||||
wheel
|
wheel
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cd /extract
|
cd /extract
|
||||||
pip install -U pytest pytest-mock && pip install --no-deps . && pytest "$@"
|
mkdir -p tests
|
||||||
|
ln -sf /extract/data tests/data
|
||||||
|
pip install -U pytest pytest-mock && pytest "$@"
|
||||||
|
Loading…
Reference in New Issue