pyportion 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Portion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyportion
3
+ Version: 0.0.1
4
+ Summary: Python CLI to manage your projects
5
+ Home-page: https://github.com/murtadapy/
6
+ Author: Murtada Altarouti
7
+ Author-email: murtada.altarouti@gmail.com
8
+ License: MIT
9
+ Project-URL: Bug Tracker, https://github.com/pyportion/pyportion/issues
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+ # PyPortion
15
+
16
+ PyPortion CLI helps you kickstart new projects and manage existing ones with ease. It streamlines project setup, enforces a clean and scalable structure, and lets you focus on delivering high-quality applications
17
+
18
+ ## Features
19
+ * 🚀 Quick start – Scaffold new projects in seconds
20
+ * 🛠️ Project management – Easily maintain and organize existing projects
21
+ * 📦 Scalable structure – Enforces a clean, maintainable architecture
22
+ * 🔄 Consistency – Keeps your project structure up to standard
23
+
24
+
25
+ ## Get started
26
+
27
+ ### Install pyportion
28
+ ```bash
29
+ pip install pyportion
30
+ ```
@@ -0,0 +1,17 @@
1
+ # PyPortion
2
+
3
+ PyPortion CLI helps you kickstart new projects and manage existing ones with ease. It streamlines project setup, enforces a clean and scalable structure, and lets you focus on delivering high-quality applications
4
+
5
+ ## Features
6
+ * 🚀 Quick start – Scaffold new projects in seconds
7
+ * 🛠️ Project management – Easily maintain and organize existing projects
8
+ * 📦 Scalable structure – Enforces a clean, maintainable architecture
9
+ * 🔄 Consistency – Keeps your project structure up to standard
10
+
11
+
12
+ ## Get started
13
+
14
+ ### Install pyportion
15
+ ```bash
16
+ pip install pyportion
17
+ ```
File without changes
@@ -0,0 +1,4 @@
1
+ from portion.portion import Portion
2
+
3
+ if __name__ == "__main__":
4
+ Portion().run()
@@ -0,0 +1,6 @@
1
+ from .command import CommandBase
2
+
3
+
4
+ __all__ = [
5
+ "CommandBase",
6
+ ]
@@ -0,0 +1,13 @@
1
+ from abc import ABC
2
+ from abc import abstractmethod
3
+
4
+ from portion.core import Logger
5
+
6
+
7
+ class CommandBase(ABC):
8
+ def __init__(self, logger: Logger, **kwargs: dict) -> None:
9
+ self.logger = logger
10
+
11
+ @abstractmethod
12
+ def execute(self) -> None:
13
+ raise NotImplementedError()
@@ -0,0 +1,14 @@
1
+ from typing import Dict
2
+
3
+ from portion.base import CommandBase
4
+ from .add import AddCommand
5
+ from .new import NewCommand
6
+ from .template import TemplateCommand
7
+
8
+
9
+ def get_commands() -> Dict[str, type[CommandBase]]:
10
+ return {
11
+ "new": NewCommand,
12
+ "add": AddCommand,
13
+ "template": TemplateCommand,
14
+ }
@@ -0,0 +1,11 @@
1
+ from portion.base import CommandBase
2
+ from portion.core.logger import Logger
3
+
4
+
5
+ class AddCommand(CommandBase):
6
+ def __init__(self, logger: Logger) -> None:
7
+ super().__init__(logger=logger)
8
+
9
+ def execute(self) -> None:
10
+ self.logger.pulse("Executing add command")
11
+ self.logger.info("Done")
@@ -0,0 +1,31 @@
1
+ import os
2
+
3
+ from portion.base import CommandBase
4
+ from portion.core.logger import Logger
5
+
6
+
7
+ class NewCommand(CommandBase):
8
+ def __init__(self,
9
+ name: str,
10
+ template: str,
11
+ logger: Logger) -> None:
12
+ super().__init__(logger=logger)
13
+ self.name = name
14
+ self.template = template
15
+
16
+ def is_project_exist(self) -> bool:
17
+ return os.path.exists(self.name)
18
+
19
+ def create_project(self) -> None:
20
+ os.mkdir(self.name)
21
+
22
+ def execute(self) -> None:
23
+ self.logger.pulse("Executing create command")
24
+ if self.is_project_exist():
25
+ self.logger.error("The project is already exist")
26
+ return None
27
+
28
+ self.create_project()
29
+ self.logger.pulse("Created the project folder")
30
+
31
+ self.logger.info(f"{self.name} project has been created successfully")
@@ -0,0 +1,41 @@
1
+ import os
2
+
3
+ from platformdirs import user_data_dir
4
+ from git import Repo
5
+
6
+ from portion.base import CommandBase
7
+ from portion.core.logger import Logger
8
+
9
+
10
+ class TemplateCommand(CommandBase):
11
+ def __init__(self,
12
+ template_command: str,
13
+ logger: Logger,
14
+ link: str | None = None) -> None:
15
+ super().__init__(logger=logger)
16
+ self.template_command = template_command
17
+ self.link = link
18
+
19
+ self._pyportion_path = os.path.join(user_data_dir(), "pyportion")
20
+
21
+ def create_pyportion_dir(self) -> None:
22
+ if not os.path.exists(self._pyportion_path):
23
+ os.mkdir(self._pyportion_path)
24
+
25
+ def download_command(self) -> None:
26
+ if not self.link:
27
+ raise ValueError("The given link is not valid")
28
+
29
+ repo_name = self.link.split("/")[-1]
30
+ repo_path = os.path.join(self._pyportion_path, repo_name)
31
+ Repo.clone_from(self.link, repo_path)
32
+
33
+ def execute(self) -> None:
34
+ self.logger.pulse("Executing template command")
35
+
36
+ self.create_pyportion_dir()
37
+
38
+ if self.template_command == "download":
39
+ self.download_command()
40
+
41
+ self.logger.info("Done")
@@ -0,0 +1,8 @@
1
+ from .logger import Logger
2
+ from .parser import Parser
3
+
4
+
5
+ __all__ = [
6
+ "Logger",
7
+ "Parser",
8
+ ]
@@ -0,0 +1,27 @@
1
+ import time
2
+ import logging
3
+
4
+
5
+ logging.basicConfig(level=logging.INFO, format="%(message)s")
6
+
7
+
8
+ class Logger:
9
+ def __init__(self, quiet: bool, verbose: bool) -> None:
10
+ self.quiet = quiet
11
+ self.verbose = verbose
12
+ self._start_time = time.monotonic()
13
+ self._end_time = time.monotonic()
14
+
15
+ def pulse(self, message: str) -> None:
16
+ if not self.quiet and self.verbose:
17
+ self._end_time = time.monotonic()
18
+ taken_time = self._end_time - self._start_time
19
+ logging.info(f"[Time Taken: {taken_time:.2f}s] {message}")
20
+
21
+ def error(self, message: str) -> None:
22
+ if not self.quiet:
23
+ logging.info("Error: " + message)
24
+
25
+ def info(self, message: str) -> None:
26
+ if not self.quiet:
27
+ logging.info(message)
@@ -0,0 +1,65 @@
1
+ import argparse
2
+ from argparse import ArgumentParser
3
+ from argparse import _SubParsersAction
4
+ from argparse import Namespace
5
+
6
+
7
+ class Parser:
8
+ def __init__(self) -> None:
9
+ self.parser = argparse.ArgumentParser(description="Portion")
10
+
11
+ def _add_generic_arguments(self,
12
+ suparser: argparse.ArgumentParser) -> None:
13
+ suparser.add_argument("-q",
14
+ default=False,
15
+ help="Suppress Logging",
16
+ action="store_true")
17
+
18
+ suparser.add_argument("-v",
19
+ default=False,
20
+ help="Verbose Logging",
21
+ action="store_true")
22
+
23
+ def _new_arguments(self, parser: _SubParsersAction) -> ArgumentParser:
24
+ new: ArgumentParser = parser.add_parser("new",
25
+ help="Create a new project")
26
+ new.add_argument("name")
27
+ new.add_argument("-t", "--template", required=True)
28
+ return new
29
+
30
+ def _add_arguments(self, parser: _SubParsersAction) -> ArgumentParser:
31
+ add = parser.add_parser("add", help="Add a portion")
32
+ return add
33
+
34
+ def _template_arguments(self, parser: _SubParsersAction) -> ArgumentParser:
35
+ template: ArgumentParser = parser.add_parser("template",
36
+ help="Manage templates")
37
+ template_subparser = template.add_subparsers(
38
+ dest="template_command",
39
+ help="Allows you to manage templates")
40
+
41
+ download_parser = template_subparser.add_parser(
42
+ "download", help="Download a template")
43
+
44
+ download_parser.add_argument("link")
45
+
46
+ # list_parser = template_subparser.add_parser(
47
+ # "list", help="List all templates")
48
+
49
+ # remove_parser = template_subparser.add_parser(
50
+ # "remove", help="Remove a template")
51
+
52
+ return template
53
+
54
+ def parse(self) -> Namespace:
55
+ subparser = self.parser.add_subparsers(dest="command", required=True)
56
+ argument_parsers = [
57
+ self._new_arguments(subparser),
58
+ self._template_arguments(subparser),
59
+ # self._add_arguments(subparser),
60
+ ]
61
+
62
+ for argument_parser in argument_parsers:
63
+ self._add_generic_arguments(argument_parser)
64
+
65
+ return self.parser.parse_args()
@@ -0,0 +1,21 @@
1
+ from portion.core import Parser
2
+ from portion.core import Logger
3
+ from portion.commands import get_commands
4
+
5
+
6
+ class Portion:
7
+ def __init__(self) -> None:
8
+ parser = Parser()
9
+ self.args = parser.parse()
10
+ self.commands = get_commands()
11
+ self.logger = Logger(self.args.q, self.args.v)
12
+
13
+ def _run_command(self) -> None:
14
+ command = self.commands.get(self.args.command, None)
15
+ if command:
16
+ params = command.__init__.__code__.co_varnames[1:]
17
+ kwargs = {k: v for k, v in vars(self.args).items() if k in params}
18
+ command(logger=self.logger, **kwargs).execute()
19
+
20
+ def run(self) -> None:
21
+ self._run_command()
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyportion
3
+ Version: 0.0.1
4
+ Summary: Python CLI to manage your projects
5
+ Home-page: https://github.com/murtadapy/
6
+ Author: Murtada Altarouti
7
+ Author-email: murtada.altarouti@gmail.com
8
+ License: MIT
9
+ Project-URL: Bug Tracker, https://github.com/pyportion/pyportion/issues
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+ # PyPortion
15
+
16
+ PyPortion CLI helps you kickstart new projects and manage existing ones with ease. It streamlines project setup, enforces a clean and scalable structure, and lets you focus on delivering high-quality applications
17
+
18
+ ## Features
19
+ * 🚀 Quick start – Scaffold new projects in seconds
20
+ * 🛠️ Project management – Easily maintain and organize existing projects
21
+ * 📦 Scalable structure – Enforces a clean, maintainable architecture
22
+ * 🔄 Consistency – Keeps your project structure up to standard
23
+
24
+
25
+ ## Get started
26
+
27
+ ### Install pyportion
28
+ ```bash
29
+ pip install pyportion
30
+ ```
@@ -0,0 +1,20 @@
1
+ LICENSE
2
+ README.md
3
+ setup.cfg
4
+ setup.py
5
+ portion/__init__.py
6
+ portion/__main__.py
7
+ portion/portion.py
8
+ portion/base/__init__.py
9
+ portion/base/command.py
10
+ portion/commands/__init__.py
11
+ portion/commands/add.py
12
+ portion/commands/new.py
13
+ portion/commands/template.py
14
+ portion/core/__init__.py
15
+ portion/core/logger.py
16
+ portion/core/parser.py
17
+ pyportion.egg-info/PKG-INFO
18
+ pyportion.egg-info/SOURCES.txt
19
+ pyportion.egg-info/dependency_links.txt
20
+ pyportion.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ portion
@@ -0,0 +1,21 @@
1
+ [metadata]
2
+ name = pyportion
3
+ version = 0.0.1
4
+ author = Murtada Altarouti
5
+ author_email = murtada.altarouti@gmail.com
6
+ url = https://github.com/murtadapy/
7
+ description = Python CLI to manage your projects
8
+ long_description = file: README.md
9
+ long_description_content_type = text/markdown
10
+ license = MIT
11
+ project_urls =
12
+ Bug Tracker = https://github.com/pyportion/pyportion/issues
13
+ python_requires = >= 3.8
14
+ install_requires =
15
+ gitpython==3.1.45
16
+ platformdirs==4.4.0
17
+
18
+ [egg_info]
19
+ tag_build =
20
+ tag_date = 0
21
+
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()