Skip to content

Commit

Permalink
Merge branch 'development' into jac/release-action
Browse files Browse the repository at this point in the history
  • Loading branch information
jacalata authored Dec 5, 2024
2 parents c897906 + e2a6879 commit 0d1e513
Show file tree
Hide file tree
Showing 144 changed files with 6,775 additions and 75,996 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/generate-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.7'
python-version: '3.9'

- name: Install App and Extras
run: |
Expand Down
38 changes: 35 additions & 3 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,21 @@ jobs:
pyinstaller tabcmd-windows.spec --clean --noconfirm --distpath ./dist/windows
OUT_FILE_NAME: tabcmd.exe
ASSET_MIME: application/vnd.microsoft.portable-executable
- os: macos-13
TARGET: macos
CMD_BUILD: >
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos/
BUNDLE_NAME: tabcmd.app
OUT_FILE_NAME: tabcmd.app
APP_BINARY_FILE_NAME: tabcmd
ASSET_MIME: application/zip
- os: macos-latest
TARGET: macos
CMD_BUILD: >
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos
pyinstaller tabcmd-mac.spec --clean --noconfirm --distpath ./dist/macos/
BUNDLE_NAME: tabcmd_arm64.app
OUT_FILE_NAME: tabcmd.app
APP_BINARY_FILE_NAME: tabcmd
ASSET_MIME: application/zip
- os: ubuntu-latest
TARGET: ubuntu
Expand All @@ -49,7 +59,7 @@ jobs:

- uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9

- name: Install dependencies and build
run: |
Expand All @@ -65,12 +75,33 @@ jobs:
run: ${{matrix.CMD_BUILD}}

- name: Validate package for ${{matrix.TARGET}}
if: matrix.TARGET != 'macos'
run: ./dist/${{ matrix.TARGET }}/${{matrix.OUT_FILE_NAME}}

- uses: actions/upload-artifact@v4
- name: Validate package for Mac
if: matrix.TARGET == 'macos'
run: ./dist/${{ matrix.TARGET }}/${{ matrix.OUT_FILE_NAME }}/Contents/MacOS/${{ matrix.APP_BINARY_FILE_NAME }}

- name: Tar app bundle for Mac
if: matrix.TARGET == 'macos'
run: |
rm -f dist/${{ matrix.TARGET }}/${{ matrix.APP_BINARY_FILE_NAME }}
cd dist/${{ matrix.TARGET }}
tar -cvf ${{ matrix.BUNDLE_NAME }}.tar ${{ matrix.OUT_FILE_NAME }}
- name: Upload artifact
if: matrix.TARGET != 'macos'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.OUT_FILE_NAME }}
path: ./dist/${{ matrix.TARGET }}/${{ matrix.OUT_FILE_NAME }}

- name: Upload artifact for Mac
if: matrix.TARGET == 'macos'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.BUNDLE_NAME }}
path: ./dist/${{ matrix.TARGET }}/${{ matrix.BUNDLE_NAME }}.tar

- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
Expand All @@ -80,3 +111,4 @@ jobs:
tag: ${{ github.ref_name }}
overwrite: true
promote: true

2 changes: 1 addition & 1 deletion .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: 3.8
python-version: 3.9
- name: Build dist files
run: |
python --version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-e2-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.9', '3.10', '3']
python-version: ['3.9', '3.10', '3.11', '3.12', '3']

runs-on: ${{ matrix.os }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3']
python-version: ['3.9', '3.10', '3.11', '3.12', '3']

runs-on: ${{ matrix.os }}

Expand Down
23 changes: 12 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# general dev/ide files
*.log
*.vscode
*.csv
.idea
*.DS_Store

Expand All @@ -24,30 +23,32 @@ workon/
.coverage
pytest.xml

*.txt
# content
# todo probably want to add a workbook and ds in /res for getting started easily
*.pdf
*.png
*.twbx
*.hyper
*.twb
*.twbr
html
*.html
*.twbr
# *.twbx
# *.hyper
# *.twb
# *.twbr
# *.tdsx
**/credentials.py
*.txt
# exceptions
!tests/assets/

# doit
.doit.*

# localization intermediate files
*.po

# venv
site-packages

# local
tabcmd-dev
workon
test.junit.xml

# exceptions
!tests/assets/detailed_users.csv
*.out
73 changes: 15 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,76 +5,33 @@
[![Python tests](https://github.com/tableau/tabcmd/actions/workflows/run-tests.yml/badge.svg)](https://github.com/tableau/tabcmd/actions/workflows/run-tests.yml)
[![Pypi smoke tests](https://github.com/tableau/tabcmd/actions/workflows/python-app.yml/badge.svg)](https://github.com/tableau/tabcmd/actions/workflows/python-app.yml)

An open source, cross platform command-line utility which you can use to automate site administration tasks on your Tableau Server site.
An open source, cross platform command-line utility which you can use to automate activity on Tableau Cloud or Tableau Server.


## Download exe (or rpm/deb)
* To download the latest release as an executable see https://github.com/tableau/tabcmd/releases
## Download the app
* To download the latest release ready to use see https://github.com/tableau/tabcmd/releases
* There is no need to install: open a command line in the same folder as the exe and run
```shell
tabcmd [command_name] [--flags]
```
e.g
* `tabcmd login --username [username] --password [password] --server [server_name] --site [site_name]`
* `tabcmd createproject --name [project_name]`
* `tabcmd help`

###or
## Install on the command line

(Note: this requires Python 3.7+. Generally we will actively support versions of Python that are still in security support).
> [!TIP]
> You can also download the current latest release directly on the command line:
> ```shell
> pip install tabcmd
> ```
```shell
pip install tabcmd
```

Or install the current work-in-progress version from Git\
*Only do this if you know you want the development version, no guarantee that we won't break APIs during development*
```shell
pip install git+https://github.com/tableau/tabcmd.git@development
```

If you go this route, but want to switch back to the non-development version, you need to run the following command before installing the stable version:
### Run tabcmd
These commands can be run from the folder that you downloaded tabcmd. If you add this folder to your PATH, they can be run from any folder.
```shell
pip uninstall tabcmd
tabcmd [command_name] [--flags]
```
e.g
* `tabcmd login --username [username] --password [password] --server [server_name] --site [site_name]`
* `tabcmd createproject --name [project_name]`
* `tabcmd help`

### Run tabcmd

To run tabcmd from your local copy, from a console window in the same directory as the file tabcmd.py:

1. Clone the repo
2. Run `pip install .`

- build
> python setup.py build
- run tests
> pytest
- run tests against a live server
> python -m tabcmd login {your server info here}
> pytest -q tests\e2e\online_tests.py -r pfE
- with coverage calculation (https://coverage.readthedocs.io/en/6.3.2)
> coverage run -m pytest && coverage report -m
- autoformat your code with black (https://pypi.org/project/black/)
> black --line-length 120 tabcmd tests [--check]
- type check with mypy
> mypy tabcmd tests
- packaging is done with pyinstaller. You can only build an executable for the platform you build on.
- To package a release, we first bump the version with `doit version` and build as 2.x.0 before packaging
> pyinstaller tabcmd\tabcmd.py --clean --noconfirm
produces dist/tabcmd.exe
To run tabcmd during development, from a console window in the same directory as the file tabcmd.py:

> dist/tabcmd/tabcmd.exe --help

* `python -m tabcmd.py [command_name] [--flags]`
* Examples:
* `tabcmd.py login --username [username] --password [password] --server [server_name] --site [site_name]`
* `tabcmd.py createproject --name [project_name]`
Expand Down
Binary file removed World Indicators.tdsx
Binary file not shown.
Binary file removed WorldIndicators.tdsx
Binary file not shown.
9 changes: 5 additions & 4 deletions bin/i18n/msgfmt.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#! /usr/bin/env python3
# Written by Martin v. Löwis <[email protected]>

""" Updated to handle utf-8 files and give better error messages
"""
Fetched from https://github.com/python/cpython/blob/main/Tools/i18n/msgfmt.py
Updated to handle utf-8 files and give better error messages
TODO contribute back?
"""

Expand Down Expand Up @@ -107,7 +108,7 @@ def make(filename, outfile):
CTXT = 3

encoding = 'utf-8'
print("Assumed encoding", encoding)
print("msgfmt::Assumed encoding", encoding)

# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
Expand Down Expand Up @@ -195,7 +196,7 @@ def make(filename, outfile):
try:
l = ast.literal_eval(l)
except:
print("ERROR (skipped)", lno, msgid)
print("\tERROR (skipped)", lno, msgid)
pass
if section == CTXT:
msgctxt += l.encode(encoding)
Expand Down
29 changes: 18 additions & 11 deletions bin/i18n/prop2po.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,51 @@
"""

import click

from datetime import datetime

@click.command()
@click.argument('source', type=click.File('rt', encoding='utf-8'))
@click.argument('destination', type=click.File('wt', encoding='utf-8'))
@click.option('-l', '--language', type=click.STRING, help='The translation language')
@click.option('-p', '--project', type=click.STRING, help='The name of the project')
@click.option('-e', '--encoding', type=click.STRING, help='The encoding wanted')
def to_po(source, destination, encoding, language, project):
@click.option('-c', '--copyright', type=click.STRING, help='The person/organization holding copyright')
def to_po(source, destination, encoding, language, project, copyright):
"""Converts a property file to a Gettext PO file.
SOURCE is the path of the property file to convert.
DESTINATION is the path of the Gettext PO file to create
"""

year = datetime.now().strftime('%Y')
header = """msgid ""
msgstr ""
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset={encoding}\\n"
"MIME-Version: 1.0\\n\\n"
"Content-Type: text/plain; charset={encoding}\\n\\n"
"Content-Transfer-Encoding: 8bit\\n"
"X-Generator: prop2po\\n"
"Project-Id-Version: {project}\\n"
"Language: {language}\\n"
# Copyright (C) YEAR Tableau Software
"""
# Copyright (C) {year} {copyright}
"""

lines = source.readlines()
print(lines)
destination.write(header.format(
language=language,
project=project,
encoding=encoding
encoding=encoding,
year=year,
copyright=copyright
))
for line in lines:
if not line.isspace():
parts = line.split('=')
# Split only on the first instance of '=' so that the character can also appear in the string
parts = line.split('=', 1)
# TODO it fails on comments/lines with less than two parts after splitting
destination.write('#:\n' + 'msgid "' + parts[0] + '"\n' 'msgstr "' + parts[1][:-1] + '"\n\n')
try:
destination.write('#:\n' + 'msgid "' + parts[0] + '"\n' 'msgstr "' + parts[1][:-1] + '"\n\n')
except IndexError as e:
print("FAILED on line{}".format(line))


if __name__ == '__main__':
Expand Down
Loading

0 comments on commit 0d1e513

Please sign in to comment.