aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/state_impl/repos.py
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-08-23 13:34:30 +0200
committerWojtek Kosior <koszko@koszko.org>2022-09-28 12:54:52 +0200
commite255c2f353ad16d3ed0460dabe84a11b119902da (patch)
tree4e7ca46d957a898cc7ffff7924fa16411560239f /src/hydrilla/proxy/state_impl/repos.py
parent7dc7b9c2c2d4b169ad545606e2fc7ef752a5d5a2 (diff)
downloadhaketilo-hydrilla-e255c2f353ad16d3ed0460dabe84a11b119902da.tar.gz
haketilo-hydrilla-e255c2f353ad16d3ed0460dabe84a11b119902da.zip
make it possible to change repo's name and URL using web UI
Diffstat (limited to 'src/hydrilla/proxy/state_impl/repos.py')
-rw-r--r--src/hydrilla/proxy/state_impl/repos.py72
1 files changed, 50 insertions, 22 deletions
diff --git a/src/hydrilla/proxy/state_impl/repos.py b/src/hydrilla/proxy/state_impl/repos.py
index ae3b70c..2670ae9 100644
--- a/src/hydrilla/proxy/state_impl/repos.py
+++ b/src/hydrilla/proxy/state_impl/repos.py
@@ -54,6 +54,28 @@ from . import base
from . import _operations
+repo_name_regex = re.compile(r'''
+^
+(?:
+ []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ # allowed non-whitespace characters
+
+ (?: # optional additional words separated by single spaces
+ [ ]
+ []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+
+ )*
+)
+$
+''', re.VERBOSE)
+
+def sanitize_repo_name(name: str) -> str:
+ name = name.strip()
+
+ if repo_name_regex.match(name) is None:
+ raise st.RepoNameInvalid()
+
+ return name
+
+
def sanitize_repo_url(url: str) -> str:
try:
parsed = urlparse(url)
@@ -220,20 +242,39 @@ class ConcreteRepoRef(st.RepoRef):
url: t.Optional[str] = None
) -> None:
if name is not None:
- raise NotImplementedError()
+ if name.isspace():
+ raise st.RepoNameInvalid()
- if url is None:
- return
+ name = sanitize_repo_name(name)
- url = sanitize_repo_url(url)
+ if url is not None:
+ if url.isspace():
+ raise st.RepoUrlInvalid()
+
+ url = sanitize_repo_url(url)
+
+ if name is None and url is None:
+ return
with self.state.cursor(transaction=True) as cursor:
ensure_repo_not_deleted(cursor, self.id)
- cursor.execute(
- 'UPDATE repos SET url = ? WHERE repo_id = ?;',
- (url, self.id)
- )
+ if url is not None:
+ cursor.execute(
+ 'UPDATE repos SET url = ? WHERE repo_id = ?;',
+ (url, self.id)
+ )
+
+ if name is not None:
+ try:
+ cursor.execute(
+ 'UPDATE repos SET name = ? WHERE repo_id = ?;',
+ (name, self.id)
+ )
+ except sqlite3.IntegrityError:
+ raise st.RepoNameTaken()
+
+ self.state.recompute_dependencies()
def refresh(self) -> st.RepoIterationRef:
with self.state.cursor(transaction=True) as cursor:
@@ -256,7 +297,7 @@ class ConcreteRepoRef(st.RepoRef):
RemoteFileResolver(repo_url)
)
- self.state.recompute_dependencies()
+ self.state.rebuild_structures()
cursor.execute(
'''
@@ -297,19 +338,6 @@ class ConcreteRepoRef(st.RepoRef):
return make_repo_display_info(self, *row)
-repo_name_regex = re.compile(r'''
-^
-(?:
- []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+ # allowed non-whitespace characters
-
- (?: # optional additional words separated by single spaces
- [ ]
- []a-zA-Z0-9()<>^&$.!,?@#|;:%"'*{}[/_=+-]+
- )*
-)
-$
-''', re.VERBOSE)
-
@dc.dataclass(frozen=True)
class ConcreteRepoStore(st.RepoStore):
state: base.HaketiloStateWithFields