developer-assistant 0.3.0__tar.gz → 0.3.5__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.
- {developer_assistant-0.3.0/developer_assistant.egg-info → developer_assistant-0.3.5}/PKG-INFO +29 -7
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/PYPI.md +28 -3
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/README.md +44 -11
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/default/test-project.ini +3 -1
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/interface.py +19 -12
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/intro.md +22 -3
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/modules/config_manager.py +1 -2
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/modules/opener.py +0 -2
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/modules/projects_manager.py +28 -25
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/modules/version_logic.py +95 -85
- developer_assistant-0.3.5/da/templates/changelog_template.txt +5 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5/developer_assistant.egg-info}/PKG-INFO +29 -7
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/pyproject.toml +1 -4
- developer_assistant-0.3.0/da/templates/changelog_template.txt +0 -6
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/LICENSE +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/__init__.py +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/default/default-changelog.md +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/default/default-memory.ini +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/modules/__init__.py +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/templates/entry_template.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/da/templates/header_template.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/SOURCES.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/dependency_links.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/entry_points.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/requires.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/top_level.txt +0 -0
- {developer_assistant-0.3.0 → developer_assistant-0.3.5}/setup.cfg +0 -0
{developer_assistant-0.3.0/developer_assistant.egg-info → developer_assistant-0.3.5}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: developer-assistant
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: A lightweight TUI app for managing and simplifying your Markdown changelogs.
|
|
5
5
|
License: The MIT License (MIT)
|
|
6
6
|
|
|
@@ -12,11 +12,8 @@ License: The MIT License (MIT)
|
|
|
12
12
|
|
|
13
13
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
14
|
Project-URL: Homepage, https://github.com/Ivory-Hubert/Developer-Assistant
|
|
15
|
-
Project-URL: Repository, https://github.com/Ivory-Hubert/Developer-Assistant.git
|
|
16
|
-
Project-URL: Issues, https://github.com/Ivory-Hubert/Developer-Assistant/issues
|
|
17
15
|
Project-URL: Changelog, https://github.com/Ivory-Hubert/Developer-Assistant/blob/main/CHANGELOG.md
|
|
18
16
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
20
17
|
Classifier: Operating System :: OS Independent
|
|
21
18
|
Classifier: Environment :: Console
|
|
22
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -32,6 +29,9 @@ Dynamic: license-file
|
|
|
32
29
|
# Developer Assistant
|
|
33
30
|
|
|
34
31
|
## Installing from PyPI
|
|
32
|
+
|
|
33
|
+
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same process is used for new profiles.
|
|
34
|
+
|
|
35
35
|
**Using uv:**
|
|
36
36
|
`uv tool install developer-assistant`
|
|
37
37
|
|
|
@@ -53,17 +53,18 @@ A. **Using uv:** `uv tool upgrade developer-assistant`
|
|
|
53
53
|
|
|
54
54
|
B. **Using pip:** `python -m pip install -U developer-assistant`
|
|
55
55
|
|
|
56
|
+
|
|
56
57
|
## Introduction
|
|
57
58
|
|
|
58
59
|
### What does this tool do?
|
|
59
|
-
Developer Assistant is a lightweight TUI
|
|
60
|
+
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
60
61
|
|
|
61
|
-
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are and what's the last version number.
|
|
62
|
+
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
62
63
|
|
|
63
64
|
Your files are kept safe at all times. Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
64
65
|
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
### Using the program.
|
|
67
68
|
1. **What *not* to do**
|
|
68
69
|
|
|
69
70
|
Don't change the folder structure or modify variable names inside `.ini` files.
|
|
@@ -88,14 +89,33 @@ The program comes with the "Default" profile, you can choose to either stick wit
|
|
|
88
89
|
|
|
89
90
|
Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
90
91
|
|
|
92
|
+
---
|
|
93
|
+
|
|
91
94
|
**Customizable templates**
|
|
92
95
|
|
|
93
96
|
In the **local** `Templates/` folder you can modify the template contents to your liking - **just avoid changing the `{{placeholder}}` names**.
|
|
94
97
|
|
|
98
|
+
Templates come in three flavours:
|
|
99
|
+
|
|
100
|
+
* changelog_template.txt - *Changelog title*
|
|
101
|
+
|
|
102
|
+
* header_template.txt - *Version and date*
|
|
103
|
+
|
|
104
|
+
* entry_template.txt - *Change entry and comments*
|
|
105
|
+
|
|
106
|
+
|
|
95
107
|
**Linked projects all in one place**
|
|
96
108
|
|
|
97
109
|
The `Projects/` folder holds the `.ini` files you create when starting a new project with DA.
|
|
98
110
|
|
|
111
|
+
[Project.ini example](./documents/project-example.ini)
|
|
112
|
+
|
|
113
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even when provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
114
|
+
|
|
115
|
+
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
99
119
|
**Safe changelog updates**
|
|
100
120
|
|
|
101
121
|
Before applying any changes, your previous `CHANGELOG.md` is automatically backed up into your project folder.
|
|
@@ -104,10 +124,12 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
104
124
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
105
125
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
106
126
|
|
|
127
|
+
|
|
107
128
|
**Ease of navigation**
|
|
108
129
|
|
|
109
130
|
You can access files/folders and configuration straight from the menus, so you shouldn't find yourself searching through the program's directory or even your local user data very often.
|
|
110
131
|
|
|
132
|
+
|
|
111
133
|
**Configuration**
|
|
112
134
|
|
|
113
135
|
The `memory.ini` file does exactly what you'd expect, it features:
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Developer Assistant
|
|
2
2
|
|
|
3
3
|
## Installing from PyPI
|
|
4
|
+
|
|
5
|
+
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same process is used for new profiles.
|
|
6
|
+
|
|
4
7
|
**Using uv:**
|
|
5
8
|
`uv tool install developer-assistant`
|
|
6
9
|
|
|
@@ -22,17 +25,18 @@ A. **Using uv:** `uv tool upgrade developer-assistant`
|
|
|
22
25
|
|
|
23
26
|
B. **Using pip:** `python -m pip install -U developer-assistant`
|
|
24
27
|
|
|
28
|
+
|
|
25
29
|
## Introduction
|
|
26
30
|
|
|
27
31
|
### What does this tool do?
|
|
28
|
-
Developer Assistant is a lightweight TUI
|
|
32
|
+
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
29
33
|
|
|
30
|
-
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are and what's the last version number.
|
|
34
|
+
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
31
35
|
|
|
32
36
|
Your files are kept safe at all times. Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
33
37
|
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
### Using the program.
|
|
36
40
|
1. **What *not* to do**
|
|
37
41
|
|
|
38
42
|
Don't change the folder structure or modify variable names inside `.ini` files.
|
|
@@ -57,14 +61,33 @@ The program comes with the "Default" profile, you can choose to either stick wit
|
|
|
57
61
|
|
|
58
62
|
Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
59
63
|
|
|
64
|
+
---
|
|
65
|
+
|
|
60
66
|
**Customizable templates**
|
|
61
67
|
|
|
62
68
|
In the **local** `Templates/` folder you can modify the template contents to your liking - **just avoid changing the `{{placeholder}}` names**.
|
|
63
69
|
|
|
70
|
+
Templates come in three flavours:
|
|
71
|
+
|
|
72
|
+
* changelog_template.txt - *Changelog title*
|
|
73
|
+
|
|
74
|
+
* header_template.txt - *Version and date*
|
|
75
|
+
|
|
76
|
+
* entry_template.txt - *Change entry and comments*
|
|
77
|
+
|
|
78
|
+
|
|
64
79
|
**Linked projects all in one place**
|
|
65
80
|
|
|
66
81
|
The `Projects/` folder holds the `.ini` files you create when starting a new project with DA.
|
|
67
82
|
|
|
83
|
+
[Project.ini example](./documents/project-example.ini)
|
|
84
|
+
|
|
85
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even when provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
86
|
+
|
|
87
|
+
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
68
91
|
**Safe changelog updates**
|
|
69
92
|
|
|
70
93
|
Before applying any changes, your previous `CHANGELOG.md` is automatically backed up into your project folder.
|
|
@@ -73,10 +96,12 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
73
96
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
74
97
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
75
98
|
|
|
99
|
+
|
|
76
100
|
**Ease of navigation**
|
|
77
101
|
|
|
78
102
|
You can access files/folders and configuration straight from the menus, so you shouldn't find yourself searching through the program's directory or even your local user data very often.
|
|
79
103
|
|
|
104
|
+
|
|
80
105
|
**Configuration**
|
|
81
106
|
|
|
82
107
|
The `memory.ini` file does exactly what you'd expect, it features:
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
> **A lightweight TUI app for managing and simplifying your Markdown changelogs.**
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
> `pip install developer-assistant`
|
|
7
7
|
|
|
8
|
-
* **
|
|
8
|
+
* **Installation:** detailed instructions in [SETUP](./SETUP.md)
|
|
9
|
+
|
|
10
|
+
* **Changes:** yes, I keep a [CHANGELOG](./CHANGELOG.md)
|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
@@ -19,6 +21,8 @@
|
|
|
19
21
|
## Appearance
|
|
20
22
|
|
|
21
23
|
### Coloured, easy-to-use menus
|
|
24
|
+
A comfortable interface with a modern polish, built the good old way:
|
|
25
|
+
|
|
22
26
|

|
|
23
27
|
|
|
24
28
|
### Beautiful changelog previews
|
|
@@ -30,9 +34,9 @@ Preview your Markdown changelogs directly in the terminal with Rich rendering:
|
|
|
30
34
|
## Introduction
|
|
31
35
|
|
|
32
36
|
### What does this tool do?
|
|
33
|
-
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for each profile to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
37
|
+
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
34
38
|
|
|
35
|
-
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are and what's the last version number.
|
|
39
|
+
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
36
40
|
|
|
37
41
|
Your files are kept safe at all times. Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
38
42
|
|
|
@@ -55,22 +59,43 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
55
59
|
|
|
56
60
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
57
61
|
|
|
58
|
-
|
|
62
|
+
> [!TIP]
|
|
63
|
+
> You can access its content quickly when going to: `Main menu / Settings`
|
|
59
64
|
|
|
60
65
|
**Profiles for seperate projects and templates**
|
|
61
66
|
|
|
62
67
|
The program comes with the "Default" profile, you can choose to either stick with this one or create your own profiles in `Main menu / Profiles`. Each profile has seperate projects and they can't be accessed by other profiles. You can choose to customize the templates seperately too.
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
> [!NOTE]
|
|
70
|
+
> Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
71
|
+
|
|
72
|
+
---
|
|
65
73
|
|
|
66
74
|
**Customizable templates**
|
|
67
75
|
|
|
68
76
|
In the **local** `Templates/` folder you can modify the template contents to your liking - **just avoid changing the `{{placeholder}}` names**.
|
|
69
77
|
|
|
78
|
+
Templates come in three flavours:
|
|
79
|
+
|
|
80
|
+
* changelog_template.txt - *Changelog title*
|
|
81
|
+
|
|
82
|
+
* header_template.txt - *Version and date*
|
|
83
|
+
|
|
84
|
+
* entry_template.txt - *Change entry and comments*
|
|
85
|
+
|
|
86
|
+
|
|
70
87
|
**Linked projects all in one place**
|
|
71
88
|
|
|
72
89
|
The `Projects/` folder holds the `.ini` files you create when starting a new project with DA.
|
|
73
90
|
|
|
91
|
+
[Project.ini example](./documents/project-example.ini)
|
|
92
|
+
|
|
93
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even when provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
94
|
+
|
|
95
|
+
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
74
99
|
**Safe changelog updates**
|
|
75
100
|
|
|
76
101
|
Before applying any changes, your previous `CHANGELOG.md` is automatically backed up into your project folder.
|
|
@@ -79,10 +104,12 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
79
104
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
80
105
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
81
106
|
|
|
107
|
+
|
|
82
108
|
**Ease of navigation**
|
|
83
109
|
|
|
84
110
|
You can access files/folders and configuration straight from the menus, so you shouldn't find yourself searching through the program's directory or even your local user data very often.
|
|
85
111
|
|
|
112
|
+
|
|
86
113
|
**Configuration**
|
|
87
114
|
|
|
88
115
|
The `memory.ini` file does exactly what you'd expect, it features:
|
|
@@ -97,7 +124,8 @@ The `memory.ini` file does exactly what you'd expect, it features:
|
|
|
97
124
|
|
|
98
125
|
Last project & active profile get updated automatically, the rest are up to you.
|
|
99
126
|
|
|
100
|
-
|
|
127
|
+
> [!TIP]
|
|
128
|
+
> **`Ctrl+C` works everywhere to quickly exit DA.**
|
|
101
129
|
|
|
102
130
|
---
|
|
103
131
|
|
|
@@ -113,10 +141,15 @@ Once configured, you can create as many changelog entries as you want by picking
|
|
|
113
141
|
Two possibilities, depending on how you installed.
|
|
114
142
|
|
|
115
143
|
### 1. Installed from PyPI
|
|
116
|
-
A. **Using uv:**
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
A. **Using uv:**
|
|
145
|
+
```bash
|
|
146
|
+
uv tool upgrade developer-assistant
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
B. **Using pip:**
|
|
150
|
+
```bash
|
|
151
|
+
python -m pip install -U developer-assistant
|
|
152
|
+
```
|
|
120
153
|
|
|
121
154
|
### 2. Installed from a local clone
|
|
122
155
|
*Run all terminal commands in the repo folder*
|
|
@@ -3,5 +3,7 @@ edited =
|
|
|
3
3
|
owner = Default
|
|
4
4
|
path = C:\Users\...\Developer-Assistant\test-project
|
|
5
5
|
changelog = C:\Users\...\Developer-Assistant\test-project\CHANGELOG.md
|
|
6
|
-
version = 1.0.0
|
|
6
|
+
version = 1.0.0
|
|
7
|
+
command = git add CHANGELOG.md
|
|
8
|
+
;; the command could be anything, DA will run it in your project folder if you add it (runs in "Format & commit")
|
|
7
9
|
cloud =
|
|
@@ -17,7 +17,7 @@ from importlib import resources
|
|
|
17
17
|
|
|
18
18
|
class Interface:
|
|
19
19
|
def __init__(self):
|
|
20
|
-
self.version = "0.3.
|
|
20
|
+
self.version = "0.3.5"
|
|
21
21
|
self.clear = 'cls' if platform.system() == 'Windows' else 'clear'
|
|
22
22
|
|
|
23
23
|
title = f"DA - {self.version}"
|
|
@@ -104,7 +104,7 @@ class Interface:
|
|
|
104
104
|
while True:
|
|
105
105
|
os.system(self.clear)
|
|
106
106
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu")
|
|
107
|
-
print(self.header
|
|
107
|
+
print(self.header)
|
|
108
108
|
print("E. Exit\n")
|
|
109
109
|
print("Last project:")
|
|
110
110
|
print(colored(last_project, f"{self.color}"))
|
|
@@ -116,7 +116,7 @@ class Interface:
|
|
|
116
116
|
|
|
117
117
|
if choice.lower() == "e":
|
|
118
118
|
os.system(self.clear)
|
|
119
|
-
print(self.header
|
|
119
|
+
print(self.header)
|
|
120
120
|
print("Bye!")
|
|
121
121
|
time.sleep(1)
|
|
122
122
|
return "exit"
|
|
@@ -131,14 +131,14 @@ class Interface:
|
|
|
131
131
|
return "settings"
|
|
132
132
|
else:
|
|
133
133
|
print("")
|
|
134
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
134
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
135
135
|
time.sleep(1)
|
|
136
136
|
|
|
137
137
|
def settings(self):
|
|
138
138
|
while True:
|
|
139
139
|
os.system(self.clear)
|
|
140
140
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Settings")
|
|
141
|
-
print(self.header
|
|
141
|
+
print(self.header)
|
|
142
142
|
print("E. Back\n")
|
|
143
143
|
|
|
144
144
|
print(colored("Configuration options", attrs=["underline"]))
|
|
@@ -166,14 +166,14 @@ class Interface:
|
|
|
166
166
|
Opener.open(self.config.templates_folder)
|
|
167
167
|
else:
|
|
168
168
|
print("")
|
|
169
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
169
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
170
170
|
time.sleep(1)
|
|
171
171
|
|
|
172
172
|
def profiles(self):
|
|
173
173
|
while True:
|
|
174
174
|
os.system(self.clear)
|
|
175
175
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Profiles")
|
|
176
|
-
print(self.header
|
|
176
|
+
print(self.header)
|
|
177
177
|
print("E. Back\n")
|
|
178
178
|
|
|
179
179
|
print("1. Create a new profile")
|
|
@@ -189,7 +189,7 @@ class Interface:
|
|
|
189
189
|
self.switch_profile()
|
|
190
190
|
else:
|
|
191
191
|
print("")
|
|
192
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
192
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
193
193
|
time.sleep(1)
|
|
194
194
|
|
|
195
195
|
def switch_profile(self):
|
|
@@ -256,9 +256,17 @@ class Interface:
|
|
|
256
256
|
self.memory = self.config.load_memory()
|
|
257
257
|
|
|
258
258
|
self.color = self.memory.get('color') or "light_blue"
|
|
259
|
-
self.header = (colored(" Developer Assistant ", f"{self.color}"))
|
|
260
259
|
self.user_path = os.environ.get('USERPROFILE') or os.environ.get('HOME', 'User')
|
|
261
260
|
|
|
261
|
+
brand = (colored(" Developer Assistant ", f"{self.color}"))
|
|
262
|
+
text = " Developer Assistant "
|
|
263
|
+
|
|
264
|
+
columns, _ = shutil.get_terminal_size()
|
|
265
|
+
pad_size = (columns - len(text)) // 2
|
|
266
|
+
bars = "=" * max(0, pad_size)
|
|
267
|
+
|
|
268
|
+
self.header = f"{bars}{brand}{bars}"
|
|
269
|
+
|
|
262
270
|
def local_init(self):
|
|
263
271
|
default_files = resources.files("da.default")
|
|
264
272
|
dest = self.config.memory_ini
|
|
@@ -268,7 +276,7 @@ class Interface:
|
|
|
268
276
|
shutil.copy(item, dest)
|
|
269
277
|
|
|
270
278
|
self.config.projects_folder.mkdir(parents=True, exist_ok=True)
|
|
271
|
-
|
|
279
|
+
|
|
272
280
|
dest = self.config.projects_folder
|
|
273
281
|
for item in default_files.iterdir():
|
|
274
282
|
if item.name == "test-project.ini":
|
|
@@ -283,9 +291,8 @@ class Interface:
|
|
|
283
291
|
|
|
284
292
|
readme_content = resources.files("da").joinpath("intro.md").read_text()
|
|
285
293
|
|
|
286
|
-
MARKDOWN = readme_content
|
|
287
294
|
console = Console()
|
|
288
|
-
md = Markdown(
|
|
295
|
+
md = Markdown(readme_content)
|
|
289
296
|
console.print(md)
|
|
290
297
|
|
|
291
298
|
input("\nContinue..." + colored("[Enter]", f"{self.color}"))
|
|
@@ -31,13 +31,15 @@ Don't change the folder structure or modify variable names inside `.ini` files.
|
|
|
31
31
|
|
|
32
32
|
The `da-ui/` folder and subfolders will be created automatically.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
> Tip:
|
|
35
|
+
> You can access its content quickly when going to: `Main menu / Settings`
|
|
35
36
|
|
|
36
37
|
**Profiles for seperate projects and templates**
|
|
37
38
|
|
|
38
39
|
The program comes with the "Default" profile, you can choose to either stick with this one or create your own profiles in `Main menu / Profiles`. Each profile has seperate projects and they can't be accessed by other profiles. You can choose to customize the templates seperately too.
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
> Note:
|
|
42
|
+
> Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
41
43
|
|
|
42
44
|
---
|
|
43
45
|
|
|
@@ -45,10 +47,25 @@ Migrating a project or template from one profile to another is currently manual,
|
|
|
45
47
|
|
|
46
48
|
In the **local** `Templates/` folder you can modify the template contents to your liking - **just avoid changing the `{{placeholder}}` names**.
|
|
47
49
|
|
|
50
|
+
Templates come in three flavours:
|
|
51
|
+
|
|
52
|
+
* changelog_template.txt - *Changelog title*
|
|
53
|
+
|
|
54
|
+
* header_template.txt - *Version and date*
|
|
55
|
+
|
|
56
|
+
* entry_template.txt - *Change entry and comments*
|
|
57
|
+
|
|
58
|
+
|
|
48
59
|
**Linked projects all in one place**
|
|
49
60
|
|
|
50
61
|
The `Projects/` folder holds the `.ini` files you create when starting a new project with DA.
|
|
51
62
|
|
|
63
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even when provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
64
|
+
|
|
65
|
+
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
52
69
|
**Safe changelog updates**
|
|
53
70
|
|
|
54
71
|
Before applying any changes, your previous `CHANGELOG.md` is automatically backed up into your project folder.
|
|
@@ -57,10 +74,12 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
57
74
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
58
75
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
59
76
|
|
|
77
|
+
|
|
60
78
|
**Ease of navigation**
|
|
61
79
|
|
|
62
80
|
You can access files/folders and configuration straight from the menus, so you shouldn't find yourself searching through the program's directory or even your local user data very often.
|
|
63
81
|
|
|
82
|
+
|
|
64
83
|
**Configuration**
|
|
65
84
|
|
|
66
85
|
The `memory.ini` file does exactly what you'd expect, it features:
|
|
@@ -75,4 +94,4 @@ The `memory.ini` file does exactly what you'd expect, it features:
|
|
|
75
94
|
|
|
76
95
|
Last project & active profile get updated automatically, the rest are up to you.
|
|
77
96
|
|
|
78
|
-
**`Ctrl+C` works everywhere to quickly exit DA.**
|
|
97
|
+
> **`Ctrl+C` works everywhere to quickly exit DA.**
|
|
@@ -65,7 +65,6 @@ class ConfigManager:
|
|
|
65
65
|
return
|
|
66
66
|
|
|
67
67
|
def project_ini(self):
|
|
68
|
-
#==Create new project ini==
|
|
69
68
|
project_parser = configparser.ConfigParser()
|
|
70
69
|
project_parser["SETTINGS"] = self.data
|
|
71
70
|
|
|
@@ -77,7 +76,6 @@ class ConfigManager:
|
|
|
77
76
|
return
|
|
78
77
|
|
|
79
78
|
def load_project(self):
|
|
80
|
-
#==Return project ini variables==
|
|
81
79
|
project_parser = configparser.ConfigParser()
|
|
82
80
|
project_parser.read(self.new_project_ini)
|
|
83
81
|
|
|
@@ -88,6 +86,7 @@ class ConfigManager:
|
|
|
88
86
|
'path': prj.get('path'),
|
|
89
87
|
'changelog': prj.get('changelog'),
|
|
90
88
|
'version': prj.get('version'),
|
|
89
|
+
'command': prj.get('command'),
|
|
91
90
|
'cloud': prj.get('cloud')
|
|
92
91
|
}
|
|
93
92
|
|
|
@@ -7,12 +7,10 @@ from termcolor import colored
|
|
|
7
7
|
class Opener:
|
|
8
8
|
@staticmethod
|
|
9
9
|
def open(path):
|
|
10
|
-
#==Check if path exists==
|
|
11
10
|
if not os.path.exists(path):
|
|
12
11
|
print(colored("\nThis path does not exist.", "light_red"))
|
|
13
12
|
time.sleep(1)
|
|
14
13
|
return
|
|
15
|
-
#==Open if exists==
|
|
16
14
|
else:
|
|
17
15
|
system = platform.system()
|
|
18
16
|
if system == "Windows":
|
|
@@ -5,6 +5,7 @@ import platform
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
|
|
8
|
+
from prompt_toolkit import prompt
|
|
8
9
|
from termcolor import colored
|
|
9
10
|
|
|
10
11
|
from da.modules.config_manager import ConfigManager
|
|
@@ -25,7 +26,7 @@ class ProjectsManager:
|
|
|
25
26
|
self.memory = self.config.load_memory()
|
|
26
27
|
os.system(self.clear)
|
|
27
28
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Projects")
|
|
28
|
-
print(self.header
|
|
29
|
+
print(self.header)
|
|
29
30
|
print("E. Back\n")
|
|
30
31
|
print(colored("1. Last project:", attrs=["underline"]))
|
|
31
32
|
print(colored(self.memory.get('last_project'), f"{self.color}"))
|
|
@@ -48,7 +49,7 @@ class ProjectsManager:
|
|
|
48
49
|
elif choice == "1":
|
|
49
50
|
project = self.memory.get('last_project')
|
|
50
51
|
if not project:
|
|
51
|
-
print(colored("\nLast project has not been defined...", "light_red", attrs=["
|
|
52
|
+
print(colored("\nLast project has not been defined...", "light_red", attrs=["bold"]))
|
|
52
53
|
time.sleep(1)
|
|
53
54
|
else:
|
|
54
55
|
self.load_project(f"{project}")
|
|
@@ -57,7 +58,6 @@ class ProjectsManager:
|
|
|
57
58
|
self.new_project()
|
|
58
59
|
|
|
59
60
|
elif choice.lower() in ("a", "b", "c"):
|
|
60
|
-
#==If the pinned project is empty, return an error message==
|
|
61
61
|
options_map = {
|
|
62
62
|
'a': 'pinned_project',
|
|
63
63
|
'b': 'pinned_project1',
|
|
@@ -67,7 +67,7 @@ class ProjectsManager:
|
|
|
67
67
|
project_name = self.memory.get(key)
|
|
68
68
|
if project_name == "":
|
|
69
69
|
print("")
|
|
70
|
-
print(colored(f"Project '{choice}' has not been defined...", "light_red", attrs=["
|
|
70
|
+
print(colored(f"Project '{choice}' has not been defined...", "light_red", attrs=["bold"]))
|
|
71
71
|
time.sleep(1)
|
|
72
72
|
else:
|
|
73
73
|
project = self.memory.get(key)
|
|
@@ -77,7 +77,7 @@ class ProjectsManager:
|
|
|
77
77
|
self.prf_projects()
|
|
78
78
|
else:
|
|
79
79
|
print("")
|
|
80
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
80
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
81
81
|
time.sleep(1)
|
|
82
82
|
|
|
83
83
|
def new_project(self):
|
|
@@ -86,21 +86,23 @@ class ProjectsManager:
|
|
|
86
86
|
now = datetime.now()
|
|
87
87
|
today = now.strftime("%Y-%m-%d")
|
|
88
88
|
|
|
89
|
-
print(self.header
|
|
89
|
+
print(self.header)
|
|
90
90
|
print("E. Abort/back\n")
|
|
91
91
|
|
|
92
|
-
name =
|
|
92
|
+
name = prompt("Enter new project name > ")
|
|
93
93
|
if name.lower() == "e":
|
|
94
94
|
return
|
|
95
|
-
path =
|
|
95
|
+
path = prompt("\nEnter project path > ")
|
|
96
96
|
|
|
97
|
-
changelog =
|
|
97
|
+
changelog = prompt("\nProject changelog path > ")
|
|
98
98
|
|
|
99
|
-
version =
|
|
99
|
+
version = prompt("\nCurrent project version > ")
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
command = prompt("\nCustom commit command > ")
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
#cloud = prompt("\nCloud service (not required) > ")
|
|
104
|
+
|
|
105
|
+
confirm = input("\nConfirm(Y) or abort(E) > ").strip()
|
|
104
106
|
if confirm.lower() == "e":
|
|
105
107
|
return
|
|
106
108
|
|
|
@@ -112,6 +114,7 @@ class ProjectsManager:
|
|
|
112
114
|
"path": path,
|
|
113
115
|
"changelog": changelog,
|
|
114
116
|
"version": version,
|
|
117
|
+
"command": command,
|
|
115
118
|
"cloud": ""
|
|
116
119
|
}
|
|
117
120
|
new_manager.project_ini()
|
|
@@ -119,15 +122,15 @@ class ProjectsManager:
|
|
|
119
122
|
|
|
120
123
|
else:
|
|
121
124
|
print("")
|
|
122
|
-
print(colored("Unknown option, try again...", "light_red", attrs=["
|
|
123
|
-
time.sleep(
|
|
125
|
+
print(colored("Unknown option, try again...", "light_red", attrs=["bold"]))
|
|
126
|
+
time.sleep(1)
|
|
124
127
|
return
|
|
125
128
|
|
|
126
129
|
def prf_projects(self):
|
|
127
130
|
while True:
|
|
128
131
|
os.system(self.clear)
|
|
129
132
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Projects / Profile projects")
|
|
130
|
-
print(self.header
|
|
133
|
+
print(self.header)
|
|
131
134
|
print("E. Back\n")
|
|
132
135
|
prof_prj = self.config.projects_folder
|
|
133
136
|
contents = os.listdir(prof_prj)
|
|
@@ -150,7 +153,7 @@ class ProjectsManager:
|
|
|
150
153
|
self.load_project(project)
|
|
151
154
|
else:
|
|
152
155
|
print("")
|
|
153
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
156
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
154
157
|
time.sleep(1)
|
|
155
158
|
|
|
156
159
|
def load_project(self, project):
|
|
@@ -190,7 +193,7 @@ class ProjectsManager:
|
|
|
190
193
|
|
|
191
194
|
os.system(self.clear)
|
|
192
195
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Projects / Project menu")
|
|
193
|
-
print(self.header
|
|
196
|
+
print(self.header)
|
|
194
197
|
print("E. Back\n")
|
|
195
198
|
print(colored("Chosen project:", attrs=["underline"]))
|
|
196
199
|
print(colored(project, f"{self.color}"))
|
|
@@ -208,8 +211,7 @@ class ProjectsManager:
|
|
|
208
211
|
return
|
|
209
212
|
|
|
210
213
|
elif choice == "1":
|
|
211
|
-
|
|
212
|
-
folder = Path(path)
|
|
214
|
+
folder = Path(setting.get('path'))
|
|
213
215
|
Opener.open(folder)
|
|
214
216
|
|
|
215
217
|
elif choice == "2":
|
|
@@ -223,27 +225,28 @@ class ProjectsManager:
|
|
|
223
225
|
if os.path.exists(changelog):
|
|
224
226
|
print(colored("\nThis action will overwrite your existing changelog!\n", "yellow"))
|
|
225
227
|
input("Acknowledge..." + colored("[Enter]", f"{self.color}"))
|
|
226
|
-
|
|
228
|
+
|
|
229
|
+
self.rest_bak(setting, changelog, project)
|
|
227
230
|
|
|
228
231
|
#elif choice == "5":
|
|
229
232
|
|
|
230
233
|
else:
|
|
231
234
|
print("")
|
|
232
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
235
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
233
236
|
time.sleep(1)
|
|
234
237
|
|
|
235
|
-
def rest_bak(self, setting, project):
|
|
238
|
+
def rest_bak(self, setting, changelog, project):
|
|
236
239
|
prj_path = Path(setting.get('path'))
|
|
237
240
|
has_bak = list(prj_path.glob("*.bak"))
|
|
238
241
|
|
|
239
242
|
if not has_bak:
|
|
240
243
|
print(colored(f"\nCan't find any .bak files for {project}", "yellow"))
|
|
241
|
-
time.sleep(
|
|
244
|
+
time.sleep(1)
|
|
242
245
|
return
|
|
243
246
|
|
|
244
247
|
bak = has_bak[0]
|
|
245
|
-
|
|
246
|
-
print(f"\
|
|
248
|
+
os.replace(bak, changelog)
|
|
249
|
+
print(f"\nReplaced {bak.name} with CHANGELOG.md")
|
|
247
250
|
time.sleep(1)
|
|
248
251
|
return
|
|
249
252
|
|
|
@@ -24,6 +24,7 @@ class VersionLogic:
|
|
|
24
24
|
self.user_path = user_path
|
|
25
25
|
|
|
26
26
|
self.memory = self.config.load_memory()
|
|
27
|
+
self.console = Console()
|
|
27
28
|
|
|
28
29
|
def project_menu(self, project, profile):
|
|
29
30
|
self.active_project = project
|
|
@@ -43,16 +44,16 @@ class VersionLogic:
|
|
|
43
44
|
self.setting = load_manager.load_project()
|
|
44
45
|
self.changelog_path = Path(self.setting.get('changelog'))
|
|
45
46
|
self.prj_ver = self.setting.get('version')
|
|
46
|
-
prj_path = Path(self.setting.get('path'))
|
|
47
|
+
self.prj_path = Path(self.setting.get('path'))
|
|
47
48
|
|
|
48
49
|
os.system(self.clear)
|
|
49
50
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Projects / Project menu / Changelog")
|
|
50
|
-
print(self.header
|
|
51
|
+
print(self.header)
|
|
51
52
|
print("E. Back\n")
|
|
52
53
|
print(colored("Chosen project:", attrs=["underline"]))
|
|
53
54
|
print(colored(self.active_project, f"{self.color}"))
|
|
54
55
|
print("Version: " + colored(self.prj_ver, f"{self.color}"))
|
|
55
|
-
print("\n1.
|
|
56
|
+
print("\n1. Format & commit")
|
|
56
57
|
print("2. Add new changes")
|
|
57
58
|
print("\n3. Open the changelog")
|
|
58
59
|
print("4. Preview .md changelog\n")
|
|
@@ -63,26 +64,27 @@ class VersionLogic:
|
|
|
63
64
|
return
|
|
64
65
|
|
|
65
66
|
elif choice == "1":
|
|
66
|
-
if not os.path.exists(
|
|
67
|
-
print(
|
|
68
|
-
time.sleep(1
|
|
67
|
+
if not os.path.exists(self.changelog_path):
|
|
68
|
+
print(no_path)
|
|
69
|
+
time.sleep(1)
|
|
69
70
|
else:
|
|
70
|
-
self.
|
|
71
|
+
self.finalise()
|
|
71
72
|
|
|
72
73
|
elif choice == "2":
|
|
73
|
-
if not os.path.exists(self.
|
|
74
|
-
print(
|
|
75
|
-
time.sleep(1
|
|
74
|
+
if not os.path.exists(self.prj_path):
|
|
75
|
+
print(colored("\nSystem cannot find the path to this project.", "light_red"))
|
|
76
|
+
time.sleep(1)
|
|
76
77
|
else:
|
|
77
78
|
self.update_changelog()
|
|
78
79
|
|
|
79
80
|
elif choice == "3":
|
|
80
81
|
if not os.path.exists(self.changelog_path):
|
|
81
82
|
print(no_path)
|
|
82
|
-
time.sleep(1
|
|
83
|
+
time.sleep(1)
|
|
83
84
|
continue
|
|
84
85
|
else:
|
|
85
|
-
|
|
86
|
+
method = self.check_size()
|
|
87
|
+
if method == "reject":
|
|
86
88
|
continue
|
|
87
89
|
else:
|
|
88
90
|
Opener.open(self.changelog_path)
|
|
@@ -90,55 +92,56 @@ class VersionLogic:
|
|
|
90
92
|
elif choice == "4":
|
|
91
93
|
if not os.path.exists(self.changelog_path):
|
|
92
94
|
print(no_path)
|
|
93
|
-
time.sleep(1
|
|
95
|
+
time.sleep(1)
|
|
94
96
|
else:
|
|
95
|
-
|
|
97
|
+
log_content = ""
|
|
98
|
+
with open(self.changelog_path, "r", encoding="utf-8") as f:
|
|
99
|
+
log_content = f.read()
|
|
100
|
+
self.view_md(log_content)
|
|
96
101
|
|
|
97
102
|
else:
|
|
98
103
|
print("")
|
|
99
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
104
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
100
105
|
time.sleep(1)
|
|
101
106
|
|
|
102
|
-
def
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
print("E. Back/abort\n")
|
|
106
|
-
|
|
107
|
-
if os.path.exists(self.changelog_path):
|
|
108
|
-
print(colored("This action will overwrite your existing changelog!\n", "yellow"))
|
|
109
|
-
input("Acknowledge..." + colored("[Enter]\n", f"{self.color}"))
|
|
107
|
+
def finalise(self):
|
|
108
|
+
with open(self.changelog_path, "r", encoding="utf-8") as f:
|
|
109
|
+
existing = f.read()
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
if version.lower() == "e":
|
|
113
|
-
return
|
|
114
|
-
change_type = input("\nChange type > ")
|
|
111
|
+
template = self.template_loader("changelog_template.txt")
|
|
115
112
|
|
|
116
|
-
|
|
113
|
+
combined = template + "\n" + existing
|
|
117
114
|
|
|
118
|
-
|
|
115
|
+
prj_dir = self.changelog_path.parent
|
|
116
|
+
fd, temp_path = tempfile.mkstemp(dir=prj_dir, text=True)
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
try:
|
|
119
|
+
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
|
120
|
+
f.write(combined)
|
|
121
|
+
f.flush()
|
|
123
122
|
|
|
124
|
-
|
|
125
|
-
"date": self.today,
|
|
126
|
-
"version": version,
|
|
127
|
-
"type": change_type,
|
|
128
|
-
"changes": entry,
|
|
129
|
-
"comments": comment
|
|
130
|
-
}
|
|
123
|
+
os.replace(temp_path, self.changelog_path)
|
|
131
124
|
|
|
132
|
-
|
|
125
|
+
except Exception as e:
|
|
126
|
+
if os.path.exists(temp_path):
|
|
127
|
+
os.remove(temp_path)
|
|
128
|
+
raise e
|
|
133
129
|
|
|
134
|
-
|
|
130
|
+
cmd = self.setting.get('command')
|
|
135
131
|
|
|
136
|
-
|
|
137
|
-
|
|
132
|
+
if cmd.strip():
|
|
133
|
+
print("\nwill run: " + colored(f"{cmd}", f"{self.color}"))
|
|
134
|
+
print("in folder: " + colored(f"{self.prj_path}", f"{self.color}"))
|
|
135
|
+
confirm = input("\nConfirm[Enter] or abort[E] > ").strip()
|
|
136
|
+
print("")
|
|
138
137
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
if confirm.lower() == "e":
|
|
139
|
+
return
|
|
140
|
+
try:
|
|
141
|
+
subprocess.run(cmd, cwd=self.prj_path, shell=True, check=True)
|
|
142
|
+
except Exception as e:
|
|
143
|
+
print(colored("\nfailed: ", "light_red") + f"{e}")
|
|
144
|
+
input("\nReturn...[Enter]")
|
|
142
145
|
|
|
143
146
|
last_project = self.memory.get('last_project')
|
|
144
147
|
if last_project != self.active_project:
|
|
@@ -147,8 +150,10 @@ class VersionLogic:
|
|
|
147
150
|
return
|
|
148
151
|
|
|
149
152
|
def update_changelog(self):
|
|
150
|
-
if self.
|
|
151
|
-
|
|
153
|
+
if os.path.exists(self.changelog_path):
|
|
154
|
+
method = self.check_size()
|
|
155
|
+
if method == "reject":
|
|
156
|
+
return
|
|
152
157
|
|
|
153
158
|
self.change_type = None
|
|
154
159
|
self.change = None
|
|
@@ -156,7 +161,7 @@ class VersionLogic:
|
|
|
156
161
|
while True:
|
|
157
162
|
os.system(self.clear)
|
|
158
163
|
print(colored(f"{self.active_profile}", f"{self.color}") + " / Main menu / Projects / Project menu / Changelog / Add changes")
|
|
159
|
-
print(self.header
|
|
164
|
+
print(self.header)
|
|
160
165
|
print("E. Back/abort")
|
|
161
166
|
print("O. Open templog for fixes")
|
|
162
167
|
print("S. Review changes & save\n")
|
|
@@ -183,7 +188,6 @@ class VersionLogic:
|
|
|
183
188
|
|
|
184
189
|
type_choice = input(f"{self.user_path}> ").strip()
|
|
185
190
|
|
|
186
|
-
#==Assign change types to keys==
|
|
187
191
|
type_map = {
|
|
188
192
|
"1": "Added",
|
|
189
193
|
"2": "Removed",
|
|
@@ -207,7 +211,7 @@ class VersionLogic:
|
|
|
207
211
|
self.save_changes()
|
|
208
212
|
else:
|
|
209
213
|
print("")
|
|
210
|
-
print(colored("Unknown option...", "light_red", attrs=["
|
|
214
|
+
print(colored("Unknown option...", "light_red", attrs=["bold"]))
|
|
211
215
|
time.sleep(1)
|
|
212
216
|
|
|
213
217
|
def prepend_changes(self):
|
|
@@ -218,21 +222,20 @@ class VersionLogic:
|
|
|
218
222
|
with open(self.templog_path, "r", encoding="utf-8") as f:
|
|
219
223
|
existing = f.read()
|
|
220
224
|
|
|
221
|
-
#==Add the change type header if needed==
|
|
222
225
|
if header not in existing:
|
|
223
226
|
with open(self.templog_path, "a", encoding="utf-8") as f:
|
|
224
227
|
f.write(header + "\n")
|
|
225
228
|
|
|
226
229
|
while True:
|
|
227
230
|
os.system(self.clear)
|
|
228
|
-
print(self.header
|
|
231
|
+
print(self.header)
|
|
229
232
|
|
|
230
233
|
print("Chosen change type:")
|
|
231
234
|
print(colored(self.change_type, f"{self.color}"))
|
|
232
235
|
|
|
233
|
-
self.change = prompt("\nChange entry
|
|
236
|
+
self.change = prompt("\nChange entry > ")
|
|
234
237
|
|
|
235
|
-
self.comment = prompt("\nOptional comment
|
|
238
|
+
self.comment = prompt("\nOptional comment > ")
|
|
236
239
|
|
|
237
240
|
data = {
|
|
238
241
|
"changes": self.change,
|
|
@@ -246,13 +249,13 @@ class VersionLogic:
|
|
|
246
249
|
with open(self.templog_path, "a", encoding="utf-8") as f:
|
|
247
250
|
f.write(rendered + "\n")
|
|
248
251
|
|
|
249
|
-
choice = input("\
|
|
252
|
+
choice = input("\nNew type [E] or add more [Enter] > ")
|
|
250
253
|
if choice.lower() == "e":
|
|
251
254
|
return
|
|
252
255
|
|
|
253
256
|
def save_changes(self):
|
|
254
257
|
os.system(self.clear)
|
|
255
|
-
print(self.header
|
|
258
|
+
print(self.header)
|
|
256
259
|
print(colored("Please check the output file:", f"{self.color}", attrs=["underline"]))
|
|
257
260
|
|
|
258
261
|
templog_content = ""
|
|
@@ -260,18 +263,15 @@ class VersionLogic:
|
|
|
260
263
|
with open(self.templog_path, "r", encoding="utf-8") as f:
|
|
261
264
|
templog_content = f.read()
|
|
262
265
|
|
|
263
|
-
|
|
266
|
+
message = colored(f"[New version] - {self.today}\n", "magenta", attrs=["underline"])
|
|
264
267
|
|
|
265
|
-
|
|
266
|
-
console = Console()
|
|
267
|
-
md = Markdown(MARKDOWN)
|
|
268
|
-
console.print(md)
|
|
268
|
+
self.view_md(templog_content, message)
|
|
269
269
|
else:
|
|
270
270
|
print(colored("No changes added.", "light_red"))
|
|
271
271
|
time.sleep(1)
|
|
272
272
|
return
|
|
273
273
|
|
|
274
|
-
choice = input("\nContinue" + colored("[Enter]", f"{self.color}") + " or
|
|
274
|
+
choice = input("\nContinue" + colored("[Enter]", f"{self.color}") + " or add more" + colored("[E] ", f"{self.color}"))
|
|
275
275
|
|
|
276
276
|
if choice.lower() == "e":
|
|
277
277
|
return
|
|
@@ -291,10 +291,8 @@ class VersionLogic:
|
|
|
291
291
|
|
|
292
292
|
old_content = ""
|
|
293
293
|
if os.path.exists(self.changelog_path):
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
project_folder = Path(self.setting.get('path'))
|
|
297
|
-
duplicate_path = project_folder / log_name
|
|
294
|
+
log_name = "changelog.bak"
|
|
295
|
+
duplicate_path = self.prj_path / log_name
|
|
298
296
|
|
|
299
297
|
src = self.changelog_path
|
|
300
298
|
dest = duplicate_path
|
|
@@ -336,35 +334,47 @@ class VersionLogic:
|
|
|
336
334
|
time.sleep(2)
|
|
337
335
|
return
|
|
338
336
|
|
|
339
|
-
def view_md(self,
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
337
|
+
def view_md(self, log_content, message=None):
|
|
338
|
+
flag = 0
|
|
339
|
+
if not message:
|
|
340
|
+
method = self.check_size()
|
|
341
|
+
if method == "reject":
|
|
342
|
+
return
|
|
343
|
+
elif method == "print":
|
|
344
|
+
flag = 1
|
|
346
345
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
346
|
+
if message:
|
|
347
|
+
print(message)
|
|
348
|
+
else:
|
|
349
|
+
os.system(self.clear)
|
|
350
|
+
print(self.header)
|
|
351
|
+
print("")
|
|
350
352
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
353
|
+
if flag:
|
|
354
|
+
print(log_content)
|
|
355
|
+
print(colored("\nThis log is too large to render in Markdown! (Max 10MB)", "yellow"))
|
|
356
|
+
else:
|
|
357
|
+
md = Markdown(log_content)
|
|
358
|
+
self.console.print(md)
|
|
355
359
|
|
|
356
|
-
|
|
360
|
+
if not message:
|
|
361
|
+
input("\nReturn..." + colored("[Enter]", f"{self.color}"))
|
|
357
362
|
return
|
|
358
363
|
|
|
359
364
|
def check_size(self):
|
|
360
|
-
|
|
365
|
+
print_size = 10 * 1024 * 1024
|
|
366
|
+
max_size = 20 * 1024 * 1024
|
|
361
367
|
|
|
362
368
|
size = self.changelog_path.stat().st_size
|
|
363
369
|
size_mb = size / (1024 * 1024)
|
|
364
|
-
|
|
370
|
+
|
|
371
|
+
if size > max_size:
|
|
365
372
|
print(colored(f"\nChangelog too large to load safely: {size_mb:.2f} MB", "light_red"))
|
|
366
373
|
time.sleep(2)
|
|
367
|
-
return
|
|
374
|
+
return "reject"
|
|
375
|
+
|
|
376
|
+
elif size > print_size:
|
|
377
|
+
return "print"
|
|
368
378
|
|
|
369
379
|
def template_loader(self, template_file):
|
|
370
380
|
template_path = self.config.templates_folder / template_file
|
{developer_assistant-0.3.0 → developer_assistant-0.3.5/developer_assistant.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: developer-assistant
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: A lightweight TUI app for managing and simplifying your Markdown changelogs.
|
|
5
5
|
License: The MIT License (MIT)
|
|
6
6
|
|
|
@@ -12,11 +12,8 @@ License: The MIT License (MIT)
|
|
|
12
12
|
|
|
13
13
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
14
14
|
Project-URL: Homepage, https://github.com/Ivory-Hubert/Developer-Assistant
|
|
15
|
-
Project-URL: Repository, https://github.com/Ivory-Hubert/Developer-Assistant.git
|
|
16
|
-
Project-URL: Issues, https://github.com/Ivory-Hubert/Developer-Assistant/issues
|
|
17
15
|
Project-URL: Changelog, https://github.com/Ivory-Hubert/Developer-Assistant/blob/main/CHANGELOG.md
|
|
18
16
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
20
17
|
Classifier: Operating System :: OS Independent
|
|
21
18
|
Classifier: Environment :: Console
|
|
22
19
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -32,6 +29,9 @@ Dynamic: license-file
|
|
|
32
29
|
# Developer Assistant
|
|
33
30
|
|
|
34
31
|
## Installing from PyPI
|
|
32
|
+
|
|
33
|
+
The program is designed for minimal friction and simple setup. Only installation is required, on first run DA will create local user data automatically. The same process is used for new profiles.
|
|
34
|
+
|
|
35
35
|
**Using uv:**
|
|
36
36
|
`uv tool install developer-assistant`
|
|
37
37
|
|
|
@@ -53,17 +53,18 @@ A. **Using uv:** `uv tool upgrade developer-assistant`
|
|
|
53
53
|
|
|
54
54
|
B. **Using pip:** `python -m pip install -U developer-assistant`
|
|
55
55
|
|
|
56
|
+
|
|
56
57
|
## Introduction
|
|
57
58
|
|
|
58
59
|
### What does this tool do?
|
|
59
|
-
Developer Assistant is a lightweight TUI
|
|
60
|
+
Developer Assistant is a lightweight TUI for simplifying and managing your changelogs. You can customize the templates for **each profile** to match your existing format, and use DA as a central hub to access every changelog and project folder you maintain.
|
|
60
61
|
|
|
61
|
-
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are and what's the last version number.
|
|
62
|
+
You can create as many profiles as you need. Each profile gets its own **project specific** `.ini` files, created automatically through the menu based on the information you provide. These act as links that tell DA where your changelogs are, which profile owns them and what's the last version number.
|
|
62
63
|
|
|
63
64
|
Your files are kept safe at all times. Before adding new changes, your existing `CHANGELOG.md` is automatically backed up. While editing, all changes are written to a temporary file first and only prepended to & replaced with your real changelog once you confirm them.
|
|
64
65
|
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
### Using the program.
|
|
67
68
|
1. **What *not* to do**
|
|
68
69
|
|
|
69
70
|
Don't change the folder structure or modify variable names inside `.ini` files.
|
|
@@ -88,14 +89,33 @@ The program comes with the "Default" profile, you can choose to either stick wit
|
|
|
88
89
|
|
|
89
90
|
Migrating a project or template from one profile to another is currently manual, **make sure to also change the "*owner*" value in `.ini` files accordingly**.
|
|
90
91
|
|
|
92
|
+
---
|
|
93
|
+
|
|
91
94
|
**Customizable templates**
|
|
92
95
|
|
|
93
96
|
In the **local** `Templates/` folder you can modify the template contents to your liking - **just avoid changing the `{{placeholder}}` names**.
|
|
94
97
|
|
|
98
|
+
Templates come in three flavours:
|
|
99
|
+
|
|
100
|
+
* changelog_template.txt - *Changelog title*
|
|
101
|
+
|
|
102
|
+
* header_template.txt - *Version and date*
|
|
103
|
+
|
|
104
|
+
* entry_template.txt - *Change entry and comments*
|
|
105
|
+
|
|
106
|
+
|
|
95
107
|
**Linked projects all in one place**
|
|
96
108
|
|
|
97
109
|
The `Projects/` folder holds the `.ini` files you create when starting a new project with DA.
|
|
98
110
|
|
|
111
|
+
[Project.ini example](./documents/project-example.ini)
|
|
112
|
+
|
|
113
|
+
The `command` variable is a custom command that DA will run in your project folder once you choose "Format & commit" in `Main menu / Projects / Project menu / Changelog`. Even when provided, it is **not** run without your confirmation, first it's printed with the folder name and you can choose to skip it.
|
|
114
|
+
|
|
115
|
+
`owner` & `edited` are filled out automatically when a new project is created and `edited` updates with every changelog update.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
99
119
|
**Safe changelog updates**
|
|
100
120
|
|
|
101
121
|
Before applying any changes, your previous `CHANGELOG.md` is automatically backed up into your project folder.
|
|
@@ -104,10 +124,12 @@ New changes are first written to a temporary file and only prepended to & replac
|
|
|
104
124
|
This ensures your existing changelog is never overwritten or corrupted, and you always have a fallback copy.
|
|
105
125
|
If the temporary changelog is present on startup you are prompted to remove or keep it.
|
|
106
126
|
|
|
127
|
+
|
|
107
128
|
**Ease of navigation**
|
|
108
129
|
|
|
109
130
|
You can access files/folders and configuration straight from the menus, so you shouldn't find yourself searching through the program's directory or even your local user data very often.
|
|
110
131
|
|
|
132
|
+
|
|
111
133
|
**Configuration**
|
|
112
134
|
|
|
113
135
|
The `memory.ini` file does exactly what you'd expect, it features:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "developer-assistant"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.5"
|
|
4
4
|
description = "A lightweight TUI app for managing and simplifying your Markdown changelogs."
|
|
5
5
|
readme = "PYPI.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -13,7 +13,6 @@ dependencies = [
|
|
|
13
13
|
]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Programming Language :: Python :: 3",
|
|
16
|
-
"License :: OSI Approved :: MIT License",
|
|
17
16
|
"Operating System :: OS Independent",
|
|
18
17
|
"Environment :: Console",
|
|
19
18
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
@@ -21,8 +20,6 @@ classifiers = [
|
|
|
21
20
|
|
|
22
21
|
[project.urls]
|
|
23
22
|
Homepage = "https://github.com/Ivory-Hubert/Developer-Assistant"
|
|
24
|
-
Repository = "https://github.com/Ivory-Hubert/Developer-Assistant.git"
|
|
25
|
-
Issues = "https://github.com/Ivory-Hubert/Developer-Assistant/issues"
|
|
26
23
|
Changelog = "https://github.com/Ivory-Hubert/Developer-Assistant/blob/main/CHANGELOG.md"
|
|
27
24
|
|
|
28
25
|
[project.scripts]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/requires.txt
RENAMED
|
File without changes
|
{developer_assistant-0.3.0 → developer_assistant-0.3.5}/developer_assistant.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|