Skip to content

Commit db1e9f8

Browse files
authored
Merge pull request #221 from jelmer/more-adm
Add more Adm bindings
2 parents 57086b6 + 3425ef4 commit db1e9f8

8 files changed

Lines changed: 405 additions & 3 deletions

File tree

.github/workflows/pydoctor.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ jobs:
3737
pip install pydoctor
3838
- name: Build API docs
3939
run: |
40+
# Remove Rust proc-macro .so build artifacts that confuse pydoctor
41+
find subvertpy -name 'lib*.so' -delete
42+
# Work around pydoctor bug: _parseFile only catches SyntaxError but
43+
# binary .so files raise UnicodeDecodeError, causing an UnboundLocalError crash.
44+
sed -i 's/except SyntaxError/except (SyntaxError, UnicodeDecodeError)/g' \
45+
"$(python -c 'import pydoctor.astbuilder; print(pydoctor.astbuilder.__file__)')"
4046
pydoctor --introspect-c-modules -c subvertpy.cfg --make-html subvertpy
4147
- name: Upload Pages artifact
4248
uses: actions/upload-pages-artifact@v3

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ edition = "2021"
1616
[workspace.dependencies]
1717
pyo3 = { version = "0.27" }
1818
#subversion = { version = ">=0.0.5" }
19-
subversion = { version = "0.1.6" }
19+
subversion = { version = "0.1.10" }
20+
#subversion = { path = "../subversion-rs" }
2021
pyo3-filelike = { version = "0.5" }

subvertpy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
ERR_WC_NOT_WORKING_COPY = ERR_WC_NOT_DIRECTORY = 155007
5454
ERR_ENTRY_EXISTS = 150002
5555
ERR_WC_PATH_NOT_FOUND = 155010
56+
ERR_WC_PATH_UNEXPECTED_STATUS = 155035
5657
ERR_CANCELLED = 200015
5758
ERR_WC_UNSUPPORTED_FORMAT = 155021
5859
ERR_UNKNOWN_CAPABILITY = 200026

tests/test_wc.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,163 @@ def test_process_committed_queue_requires_write_lock(self):
571571
)
572572

573573

574+
def test_context_manager(self):
575+
with wc.Context() as ctx:
576+
self.assertIsNotNone(ctx)
577+
result = ctx.locked(os.path.abspath("checkout"))
578+
self.assertIsInstance(result, tuple)
579+
580+
def test_close(self):
581+
ctx = wc.Context()
582+
ctx.close()
583+
584+
585+
class AdmObjTests(SubversionTestCase):
586+
def setUp(self):
587+
super().setUp()
588+
self.repos_url = self.make_client("repos", "checkout")
589+
self._adm = None
590+
591+
def tearDown(self):
592+
if self._adm is not None:
593+
self._adm.close()
594+
self._adm = None
595+
super().tearDown()
596+
597+
def _open_adm(self, **kwargs):
598+
self._adm = wc.Adm(**kwargs)
599+
return self._adm
600+
601+
def test_open(self):
602+
adm = self._open_adm(path=os.path.abspath("checkout"), write_lock=False)
603+
self.assertIsNotNone(adm)
604+
605+
def test_open_positional(self):
606+
self._adm = wc.Adm(None, os.path.abspath("checkout"))
607+
self.assertIsNotNone(self._adm)
608+
609+
def test_open_no_path(self):
610+
self.assertRaises(TypeError, wc.Adm)
611+
612+
def test_open_none_path(self):
613+
self.assertRaises(TypeError, wc.Adm, None, None)
614+
615+
def test_access_path(self):
616+
adm = self._open_adm(path=os.path.abspath("checkout"), write_lock=False)
617+
self.assertEqual(
618+
os.path.normpath(os.path.abspath("checkout")),
619+
os.path.normpath(adm.access_path()),
620+
)
621+
622+
def test_is_locked_read(self):
623+
adm = self._open_adm(path=os.path.abspath("checkout"), write_lock=False)
624+
self.assertFalse(adm.is_locked())
625+
626+
def test_is_locked_write(self):
627+
adm = self._open_adm(
628+
path=os.path.abspath("checkout"), write_lock=True, depth=-1
629+
)
630+
self.assertTrue(adm.is_locked())
631+
632+
def test_context_manager(self):
633+
with wc.Adm(path=os.path.abspath("checkout"), write_lock=False) as adm:
634+
self.assertIsNotNone(adm)
635+
self.assertEqual(
636+
os.path.normpath(os.path.abspath("checkout")),
637+
os.path.normpath(adm.access_path()),
638+
)
639+
640+
def test_is_wc_root(self):
641+
adm = self._open_adm(path=os.path.abspath("checkout"), write_lock=False)
642+
self.assertTrue(adm.is_wc_root(os.path.abspath("checkout")))
643+
644+
def test_prop_set_get(self):
645+
self.build_tree({"checkout/proptest": b"content"})
646+
self.client_add("checkout/proptest")
647+
self.client_commit("checkout", message="add proptest")
648+
adm = self._open_adm(
649+
path=os.path.abspath("checkout"), write_lock=True, depth=-1
650+
)
651+
adm.prop_set("svn:eol-style", b"native", os.path.abspath("checkout/proptest"))
652+
val = adm.prop_get("svn:eol-style", os.path.abspath("checkout/proptest"))
653+
self.assertEqual(b"native", val)
654+
655+
def test_prop_get_nonexistent(self):
656+
self.build_tree({"checkout/propnone": b"content"})
657+
self.client_add("checkout/propnone")
658+
self.client_commit("checkout", message="add propnone")
659+
adm = self._open_adm(path=os.path.abspath("checkout"), write_lock=False)
660+
val = adm.prop_get("svn:nonexistent", os.path.abspath("checkout/propnone"))
661+
self.assertIsNone(val)
662+
663+
def test_text_modified(self):
664+
self.build_tree({"checkout/txtmod": b"content"})
665+
self.client_add("checkout/txtmod")
666+
self.client_commit("checkout", message="add txtmod")
667+
adm = self._open_adm(
668+
path=os.path.abspath("checkout"), write_lock=False, depth=-1
669+
)
670+
self.assertFalse(adm.text_modified(os.path.abspath("checkout/txtmod"), False))
671+
self.build_tree({"checkout/txtmod": b"changed"})
672+
self.assertTrue(adm.text_modified(os.path.abspath("checkout/txtmod"), False))
673+
674+
def test_props_modified(self):
675+
self.build_tree({"checkout/pmod": b"content"})
676+
self.client_add("checkout/pmod")
677+
self.client_commit("checkout", message="add pmod")
678+
adm = self._open_adm(
679+
path=os.path.abspath("checkout"), write_lock=False, depth=-1
680+
)
681+
self.assertFalse(adm.props_modified(os.path.abspath("checkout/pmod")))
682+
683+
def test_conflicted(self):
684+
self.build_tree({"checkout/conflfile": b"content"})
685+
self.client_add("checkout/conflfile")
686+
self.client_commit("checkout", message="add conflfile")
687+
adm = self._open_adm(
688+
path=os.path.abspath("checkout"), write_lock=False, depth=-1
689+
)
690+
result = adm.conflicted(os.path.abspath("checkout/conflfile"))
691+
self.assertIsInstance(result, tuple)
692+
self.assertEqual(3, len(result))
693+
self.assertEqual((False, False, False), result)
694+
695+
def test_has_binary_prop(self):
696+
self.build_tree({"checkout/binfile": b"content"})
697+
self.client_add("checkout/binfile")
698+
self.client_commit("checkout", message="add binfile")
699+
adm = self._open_adm(
700+
path=os.path.abspath("checkout"), write_lock=False, depth=-1
701+
)
702+
self.assertFalse(adm.has_binary_prop(os.path.abspath("checkout/binfile")))
703+
704+
def test_add(self):
705+
self.build_tree({"checkout/addfile": b"content"})
706+
adm = self._open_adm(
707+
path=os.path.abspath("checkout"), write_lock=True, depth=-1
708+
)
709+
adm.add(os.path.abspath("checkout/addfile"))
710+
711+
def test_delete(self):
712+
self.build_tree({"checkout/delfile": b"content"})
713+
self.client_add("checkout/delfile")
714+
self.client_commit("checkout", message="add delfile")
715+
adm = self._open_adm(
716+
path=os.path.abspath("checkout"), write_lock=True, depth=-1
717+
)
718+
adm.delete(os.path.abspath("checkout/delfile"))
719+
720+
def test_delete_keep_local(self):
721+
self.build_tree({"checkout/delkeep": b"content"})
722+
self.client_add("checkout/delkeep")
723+
self.client_commit("checkout", message="add delkeep")
724+
adm = self._open_adm(
725+
path=os.path.abspath("checkout"), write_lock=True, depth=-1
726+
)
727+
adm.delete(os.path.abspath("checkout/delkeep"), keep_local=True)
728+
self.assertTrue(os.path.exists("checkout/delkeep"))
729+
730+
574731
class LockTests(TestCase):
575732
def test_create_lock(self):
576733
lock = wc.Lock()

0 commit comments

Comments
 (0)