Skip to content
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
strategy:
fail-fast: true
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: ['3.8', '3.9', '3.10']
steps:
- name: Check out repository code
uses: actions/checkout@v2
Expand All @@ -40,6 +40,9 @@ jobs:
run: tox

- name: "Upload coverage to Codecov"
uses: codecov/codecov-action@v1
uses: codecov/codecov-action@v5
with:
fail_ci_if_error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

8 changes: 4 additions & 4 deletions nak/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from nak.gateway import Gateway
from nak.settings import (CONFIG_FILE, ENV_FILE, LOG_COLOR,
ZIP_DESTINATION_DIRECTORY, ZIP_DESTINATION_PATH)
from nak.utils import (get_all_file, get_error_from_response, hide_variable,
from nak.utils import (get_all_file, get_error_from_response, hide_variable, get_lastest_build_file,
progress_bar)

logging.basicConfig(
Expand Down Expand Up @@ -63,6 +63,7 @@ def build(self, parser=None):
new_zip.write(file)

new_zip.close()
logging.info(LOG_COLOR.INFO.format(message=f'Created build file with {destination_file.split("/")[-1]}.'))
logging.info(LOG_COLOR.SUCCESS.format(message='Build successfully.'))

def push(self, parser=None):
Expand All @@ -76,11 +77,10 @@ def push(self, parser=None):
raise TypeError(LOG_COLOR.ERROR.format(
message=('No build file available. Run "nak build".')))

zip_file_list = get_all_file(path=f"./{ZIP_DESTINATION_DIRECTORY}", required_extension='.zip')
if not zip_file_list:
latest_build_file = get_lastest_build_file()
if not latest_build_file:
raise TypeError(LOG_COLOR.ERROR.format(message='Please run build before push command.'))

latest_build_file = sorted(zip_file_list, key=lambda file_name: file_name, reverse=True)[0]
file_name = latest_build_file.split("/")[-1]

logging.info(LOG_COLOR.INFO.format(message=f'Pushing to app with client_id {self.config.client_id}'))
Expand Down
20 changes: 16 additions & 4 deletions nak/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,23 @@
import time
from pathlib import Path

from nak.settings import ALLOW_FILE_EXTENSIONS, ZIP_EXCLUDE_FILES
from nak.settings import ALLOW_FILE_EXTENSIONS, ZIP_DESTINATION_DIRECTORY, ZIP_EXCLUDE_FILES


def get_latest_zip(pathfile):
return Path(os.path.relpath(pathfile)).as_posix()
def get_lastest_build_file():
path = Path(f"./{ZIP_DESTINATION_DIRECTORY}")

zip_files = [f for f in path.iterdir() if f.is_file() and f.suffix == ".zip"]
if not zip_files:
return None

zip_files_sorted = sorted(
zip_files,
key=lambda f: f.stat().st_ctime,
reverse=True
)

return zip_files_sorted[0].as_posix()
Comment thread
Djirasak marked this conversation as resolved.
Outdated


def progress_bar(iterable, prefix='', suffix='', decimals=1, length=100, fill='█', printEnd="\r"):
Expand Down Expand Up @@ -72,7 +84,7 @@ def get_error_from_response(response):
result = response.json()
error_msg = ""
for key, value in result.items():
if type(value) == list:
if isinstance(value, list):
error_msg += f'"{key}" : {" ".join(value)}'
else:
error_msg += value
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from setuptools import find_packages, setup

__version__ = '1.0.3'
__version__ = '1.0.4'

tests_require = [
"flake8==3.9.2",
"nose==1.3.7"
"pytest==7.2.2"
]

with open('README.md', 'r') as fh:
Expand Down
24 changes: 13 additions & 11 deletions tests/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from unittest.mock import MagicMock, call, mock_open, patch

from nak.command import Command
from nak.settings import LOG_COLOR
from nak.settings import LOG_COLOR, ZIP_DESTINATION_PATH


class TestCommand(unittest.TestCase):
Expand Down Expand Up @@ -106,22 +106,23 @@ def test_build_with_correct_directory_should_create_zip_file_correctly(
call.write('test2.file'),
call.close(),
]

file_name = ZIP_DESTINATION_PATH.format(app_name="app-kit").split('/')[-1]
assert log.output == [
f"INFO:root:{LOG_COLOR.INFO.format(message='file: test1.file')}",
f"INFO:root:{LOG_COLOR.INFO.format(message='file: test2.file')}",
f"INFO:root:{LOG_COLOR.INFO.format(message=f'Created build file with {file_name}.')}",
f"INFO:root:{LOG_COLOR.SUCCESS.format(message='Build successfully.')}"
]

#####
# push
#####
@patch("os.path.exists", autospec=True)
@patch("nak.command.get_all_file", autospec=True)
@patch("nak.command.Config.write_config", autospec=True)
def test_push_with_wrong_directory_should_raise_error_correctly(
self, mock_write_config, mock_get_file, mock_path_exists
self, mock_write_config, mock_path_exists
):
mock_get_file.return_value = ["test1.file", "test2.file"]
mock_path_exists.side_effect = [
# check envfile at read_config
False,
Expand All @@ -139,12 +140,13 @@ def test_push_with_wrong_directory_should_raise_error_correctly(

@patch("builtins.open", autospec=True)
@patch("os.path.exists", autospec=True)
@patch("nak.command.get_all_file", autospec=True)
@patch("nak.command.get_lastest_build_file", autospec=True)
@patch("nak.command.Config.write_config", autospec=True)
def test_push_with_failed_on_server_should_log_error_correctly(
self, mock_write_config, mock_get_file, mock_path_exists, mock_open_file
):
mock_get_file.return_value = ["test1-20200101010101.zip", "test2-20200101010102.zip"]
mock_get_file.return_value = "test1-20200101010101.zip"

mock_path_exists.side_effect = [
# check envfile at read_config
True,
Expand All @@ -165,24 +167,24 @@ def test_push_with_failed_on_server_should_log_error_correctly(
self.mock_gateway.return_value.update_app.assert_called_once_with(
files={
# send with latest file
'file': ('test2-20200101010102.zip', file)
'file': ('test1-20200101010101.zip', file)
}
)
assert log.output == [
f'INFO:root:{LOG_COLOR.INFO.format(message="Pushing to app with client_id 123456")}',
f'INFO:root:{LOG_COLOR.INFO.format(message="with filename test2-20200101010102.zip")}',
f'INFO:root:{LOG_COLOR.INFO.format(message="with filename test1-20200101010101.zip")}',
f'INFO:root:{LOG_COLOR.INFO.format(message="by username test@29next.com")}',
f"INFO:root:{LOG_COLOR.ERROR.format(message='Upload file to server failed. file size limit')}"
]

@patch("builtins.open", autospec=True)
@patch("os.path.exists", autospec=True)
@patch("nak.command.get_all_file", autospec=True)
@patch("nak.command.get_lastest_build_file", autospec=True)
@patch("nak.command.Config.write_config", autospec=True)
def test_push_with_correct_directory_should_call_gateway_correctly(
self, mock_write_config, mock_get_file, mock_path_exists, mock_open_file
):
mock_get_file.return_value = ["test1-20200101010101.zip", "test2-20200101010102.zip"]
mock_get_file.return_value = "test2-20200101010102.zip"
mock_path_exists.side_effect = [
# check envfile at read_config
True,
Expand Down Expand Up @@ -233,7 +235,7 @@ def test_push_with_no_directory_should_raise_error(
message=('No build file available. Run "nak build".'))

@patch("os.path.exists", autospec=True)
@patch("nak.command.get_all_file", autospec=True)
@patch("nak.command.get_lastest_build_file", autospec=True)
@patch("nak.command.Config.write_config", autospec=True)
def test_push_with_no_files_in_directory_should_raise_error(
self, mock_write_config, mock_get_file, mock_path_exists
Expand Down
38 changes: 38 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,41 @@ def test_get_all_file_with_required_extension_file_should_return_correctly_file_

actual = utils.get_all_file('.', required_extension='.zip')
assert actual == ['./test_zip1.zip', './test_zip2.zip']

####
# get_lastest_build_file
###
@patch("nak.utils.Path")
def test_get_lastest_build_file_with_no_zip_file_should_return_none(self, mock_path):
mock_dir = MagicMock()
mock_path.return_value = mock_dir

mock_dir.iterdir.return_value = [
MagicMock(
is_file=MagicMock(return_value=True), suffix='.txt', as_posix=MagicMock(return_value='file1.txt')),
MagicMock(
is_file=MagicMock(return_value=True), suffix='.txt', as_posix=MagicMock(return_value='file2.txt'))
]

result = utils.get_lastest_build_file()
assert result is None

@patch("nak.utils.Path")
def test_get_lastest_build_file_with_have_zip_fiile_should_return_latest_file(self, mock_path):
mock_dir = MagicMock()
mock_path.return_value = mock_dir

mock_file1 = MagicMock(
is_file=MagicMock(return_value=True), suffix='.zip', as_posix=MagicMock(return_value='file1.txt'))
mock_file1.stat.return_value.st_ctime = 1000
mock_file1.as_posix.return_value = 'file1.zip'

mock_file2 = MagicMock(
is_file=MagicMock(return_value=True), suffix='.zip', as_posix=MagicMock(return_value='file2.txt'))
mock_file2.stat.return_value.st_ctime = 2000
mock_file2.as_posix.return_value = 'file2.zip'

mock_dir.iterdir.return_value = [mock_file1, mock_file2]

result = utils.get_lastest_build_file()
assert result == 'file2.zip'
12 changes: 6 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
[tox]
envlist = py36, py37, py38, py39
envlist = py37, py38, py39, py310
skip_missing_interpreters = true

[gh-actions]
python =
3.6: py36
3.7: py37
3.8: py38
3.9: py39
3.10: py310

[testenv]
allowlist_externals = /usr/bin/test
deps =
coverage
codecov
pytest
pytest-cov
flake8
nose
codecov

commands = nosetests -v --with-coverage --cover-inclusive --cover-xml --cover-package=nak
commands = pytest --cov=nak --cov-report xml
Loading