openrewrite-remote 0.13.5__py3-none-any.whl → 0.14.0__py3-none-any.whl

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: openrewrite-remote
3
- Version: 0.13.5
3
+ Version: 0.14.0
4
4
  Summary: Remoting functionality for the OpenRewrite library.
5
5
  Author-email: "Moderne Inc." <support@moderne.io>
6
6
  License: Moderne, Inc. Commercial License
@@ -0,0 +1,24 @@
1
+ rewrite_remote/__init__.py,sha256=gl4Dpp7mYIrfNgeyh2IeW2fsj9ep9pveAK_eeoDLu7c,278
2
+ rewrite_remote/client.py,sha256=95ZCAtVOngF0ZqqKnOsrweUeGKruf3UKGPXNGTrNyy0,1853
3
+ rewrite_remote/event.py,sha256=texLJD1mcFkpBpiXAa-Rmip0Tgqm2OlBpRPHFZyWcBs,359
4
+ rewrite_remote/receiver.py,sha256=b2jMNwTfnWM0oDNjJQSWV1z_ahJ0kDZEXYdwNc4riIw,20743
5
+ rewrite_remote/remote_utils.py,sha256=gU9hN-aHxy9NF4uRqjd4OhvgPrNfDyCt3y1PtrWMCgA,10677
6
+ rewrite_remote/remoting.py,sha256=yS2sYMPPBq0gt1xalmCTLbH4VXbBqNl-EXj8ZfgA5UM,13525
7
+ rewrite_remote/sender.py,sha256=PXX0hrmeHKEge_7qWEMqNn4KYleDrFUQqhBDWTq1pus,18993
8
+ rewrite_remote/server.py,sha256=TQ1cK6eAiJgY0ZAGl4huu5urI2Cm9DJpl-k8Is-IM1M,9466
9
+ rewrite_remote/type_utils.py,sha256=qzQ2X97U8yRskjOo3F5qcFVebW2bPYFU32EpCKL-KNU,4400
10
+ rewrite_remote/handlers/__init__.py,sha256=ED6jHcYiuYpr_0vjGz0zx2lrrmJT9sDJCzIljoDfmlM,65
11
+ rewrite_remote/handlers/handler_helpers.py,sha256=xvAKAVGH56Hrjp9sbilp4v1a2_ra0L63YjXurF5K5o0,512
12
+ rewrite_remote/handlers/hello_world_handler.py,sha256=HLVukS16-PRRidlnfABT6ETXURhQYIJnTSb09PJnDek,1284
13
+ rewrite_remote/handlers/list_projects_handler.py,sha256=ukkCST7whpCxQ0omCWWw9W27Su3rFSnnEIhAS6T4iOU,2007
14
+ rewrite_remote/handlers/parse_project_sources_handler.py,sha256=mn7LVW7yu3SFFDdZlTU4i65wFhQxhkA7ttSqSs3s7Vk,2997
15
+ rewrite_remote/handlers/project_helper.py,sha256=wEohTWukfcDCNlSran1cuedg9CGeVdbhiHRD2wwpAwk,8445
16
+ rewrite_remote/handlers/pypi_manager.py,sha256=XulTdZUm5aTme7Qn-jaUvlgO6N9bKS03UUQtbxv9kYE,10247
17
+ rewrite_remote/handlers/recipe_install_handler.py,sha256=SsY7oXEJqE3mKUM_msnV0i-aUXmeUWpYjq_121ui3Z8,4920
18
+ rewrite_remote/handlers/run_recipe_load_and_visitor_handler.py,sha256=BmsKjV38LenewWvun8cknGk_oR3GoinmmsXtWKUWUak,4085
19
+ rewrite_remote/handlers/types.py,sha256=5TK_oFp-7iy1iACWisuQJsa_WHTsqcPrV9nQTZ-_xgo,518
20
+ openrewrite_remote-0.14.0.dist-info/METADATA,sha256=ydjRf-SRkjLYHaWICk1zDeKw8gKDhL11Y_hm_kB29AM,386
21
+ openrewrite_remote-0.14.0.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
22
+ openrewrite_remote-0.14.0.dist-info/entry_points.txt,sha256=SMukuF7TPjQr3IZIcH8f98-_QBCqYSbYXYrVv-5UzRI,69
23
+ openrewrite_remote-0.14.0.dist-info/top_level.txt,sha256=ansTioSZ-62aH3F2L3d1Bua0pJF4GOtgQ1PpG-CzcP0,15
24
+ openrewrite_remote-0.14.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -18,9 +18,8 @@ def hello_world_handler(
18
18
  request = cbor2.load(stream)
19
19
 
20
20
  if request != "hello":
21
- raise ValueError(f"Unexpected request: {request}")
22
- else:
23
21
  print("Did not receive 'hello' ")
22
+ raise ValueError(f"Unexpected request: {request}")
24
23
 
25
24
  # Prepare a response
26
25
  response_stream = BytesIO()
@@ -0,0 +1,95 @@
1
+ import logging
2
+ import os
3
+ import socket
4
+ from io import BytesIO
5
+ from typing import TypedDict
6
+
7
+ import cbor2
8
+
9
+ from cbor2 import dumps, CBORDecoder
10
+
11
+ from rewrite_remote.handlers.project_helper import (
12
+ find_python_files,
13
+ parse_python_sources,
14
+ )
15
+
16
+ from rewrite_remote.remoting import (
17
+ OK,
18
+ RemotingMessageType,
19
+ )
20
+
21
+ from rewrite_remote.remote_utils import COMMAND_END
22
+ from rewrite_remote.remoting import RemotingContext
23
+ from rewrite_remote.handlers.handler_helpers import respond_with_error
24
+ from rewrite_remote.remoting import RemotingMessenger
25
+
26
+
27
+ class ParseProjectSourcesArgs(TypedDict):
28
+ project_file_path: str # The path to the individual pyproject.toml
29
+ root_project_file_path: str # The path to the root pyproject.toml
30
+ repository_dir: str # The path to the root repository directory
31
+
32
+
33
+ def decode_parse_project_sources_args(
34
+ decoder: CBORDecoder,
35
+ ) -> ParseProjectSourcesArgs:
36
+ """
37
+ Decodes the arguments (order matters and must match the order encoded)
38
+ """
39
+ project_file_path = str(decoder.decode())
40
+ root_project_file_path = str(decoder.decode())
41
+ repository_dir = str(decoder.decode())
42
+
43
+ return {
44
+ "project_file_path": project_file_path,
45
+ "root_project_file_path": root_project_file_path,
46
+ "repository_dir": repository_dir,
47
+ }
48
+
49
+
50
+ def parse_project_sources_handler(
51
+ stream: BytesIO, sock: socket.socket, remoting_ctx: RemotingContext
52
+ ) -> None:
53
+ remoting_ctx.reset()
54
+
55
+ # Read input from stream
56
+ try:
57
+ data = stream.read()
58
+ decoder = CBORDecoder(BytesIO(data))
59
+ args = decode_parse_project_sources_args(decoder)
60
+ project_file_path = args.get("project_file_path")
61
+ root_project_file_path = args.get("root_project_file_path")
62
+ repository_dir = args.get("repository_dir")
63
+ except Exception as e: # pylint: disable=broad-except
64
+ respond_with_error(f"Failed to decode arguments: {e}", sock)
65
+ return
66
+
67
+ if project_file_path is None:
68
+ respond_with_error("recipe_name is required", sock)
69
+ return
70
+
71
+ # Log the request
72
+ logging.info(
73
+ "[Server] Handling parse-project-sources request: {"
74
+ "project_file_path: %s, root_project_file_path: %s, repository_dir: %s}",
75
+ project_file_path,
76
+ root_project_file_path,
77
+ repository_dir,
78
+ )
79
+
80
+ # Find all python files in the project
81
+ base_dir = os.path.dirname(project_file_path)
82
+ python_files = find_python_files(base_dir)
83
+ source_files = parse_python_sources(python_files)
84
+
85
+ # Write the response
86
+ response_stream = BytesIO()
87
+ cbor2.dump(RemotingMessageType.Response, response_stream)
88
+ cbor2.dump(OK, response_stream)
89
+ for source_file in source_files:
90
+ logging.info("Sending ${source_file.source_path}")
91
+ RemotingMessenger.send_tree(remoting_ctx, response_stream, source_file, None)
92
+ cbor2.dump(COMMAND_END, response_stream)
93
+ sock.sendall(response_stream.getvalue())
94
+
95
+ logging.info("[Server] Request completed.")
@@ -1,7 +1,14 @@
1
1
  import os
2
2
  import glob
3
3
  import toml
4
- from typing import Any
4
+ from typing import Any, List, Iterable
5
+ from pathlib import Path
6
+ from io import StringIO
7
+
8
+ from rewrite.tree import SourceFile
9
+ from rewrite.python.parser import PythonParserBuilder
10
+
11
+ from rewrite import ParserInput, InMemoryExecutionContext
5
12
 
6
13
  from dataclasses import dataclass
7
14
 
@@ -187,3 +194,47 @@ def find_sub_projects_in_project_dependencies(
187
194
  def get_absolute_path(path_to_root_toml: str, path_to_sub_project: str) -> str:
188
195
  path_to_root = os.path.dirname(path_to_root_toml)
189
196
  return os.path.abspath(os.path.join(path_to_root, path_to_sub_project))
197
+
198
+
199
+ def find_python_files(base_dir: str) -> List[str]:
200
+ """
201
+ Find all python files in the given directory and its subdirectories
202
+ """
203
+ python_files = []
204
+ for root, dirs, files in os.walk(base_dir):
205
+ for file in files:
206
+ if file.endswith(".py"):
207
+ python_files.append(os.path.join(root, file))
208
+ return python_files
209
+
210
+
211
+ def read_file_contents(path: str) -> StringIO:
212
+ """
213
+ Read the contents of the file at the given path
214
+ """
215
+ with open(path, "r", newline="", encoding="utf-8") as file:
216
+ return StringIO(file.read())
217
+
218
+
219
+ def parse_python_sources(paths: List[str]) -> List[SourceFile]:
220
+ """
221
+ Parse the given python files and return a list of SourceFile objects
222
+ """
223
+ parser = PythonParserBuilder().build()
224
+ ctx = InMemoryExecutionContext()
225
+
226
+ iterable_source_files: Iterable[SourceFile] = parser.parse_inputs(
227
+ [
228
+ ParserInput(
229
+ Path(path),
230
+ None,
231
+ True,
232
+ lambda: read_file_contents(path),
233
+ )
234
+ for path in paths
235
+ ],
236
+ None,
237
+ ctx,
238
+ )
239
+
240
+ return list(iterable_source_files)
@@ -221,7 +221,7 @@ class PyPiManager:
221
221
  module_name = module_name.replace("-", "_")
222
222
 
223
223
  try:
224
- site.main(); # We want the recently installed module to be available to introspection
224
+ site.main() # We want the recently installed module to be available to introspection
225
225
  module = importlib.import_module(module_name)
226
226
  submodules = [name for _, name, _ in pkgutil.iter_modules(module.__path__)]
227
227
 
@@ -1,6 +1,7 @@
1
1
  # type: ignore
2
2
  # Ignoring type checking for this file because there is too many errors for now
3
3
 
4
+ import struct
4
5
  from collections import OrderedDict
5
6
  from enum import Enum
6
7
  from pathlib import Path
@@ -22,8 +23,9 @@ from typing import (
22
23
  from uuid import UUID
23
24
 
24
25
  from _cbor2 import break_marker
25
- from cbor2 import CBORDecoder
26
+ from cbor2 import CBORDecoder, CBORDecodeValueError
26
27
  from cbor2._decoder import major_decoders
28
+
27
29
  from rewrite import (
28
30
  Markers,
29
31
  Marker,
@@ -33,7 +35,6 @@ from rewrite import (
33
35
  UnknownJavaMarker,
34
36
  )
35
37
  from rewrite import Tree, TreeVisitor, Cursor, FileAttributes
36
-
37
38
  from . import remote_utils, type_utils
38
39
  from .event import DiffEvent, EventType
39
40
 
@@ -276,9 +277,11 @@ class DeserializationContext:
276
277
  if get_origin(expected_type) in (List, list):
277
278
  expected_elem_type = get_args(expected_type)[0]
278
279
  array = []
279
- if subtype != 31:
280
- for _ in range(subtype):
281
- array.append(self.deserialize(expected_elem_type, decoder))
280
+ length = _decode_length(decoder, subtype, allow_indefinite=True)
281
+ if length:
282
+ for _ in range(length):
283
+ elem = self.deserialize(expected_elem_type, decoder)
284
+ array.append(elem)
282
285
  else:
283
286
  while (
284
287
  not (value := self.deserialize(expected_elem_type, decoder)) == break_marker
@@ -330,6 +333,8 @@ class DeserializationContext:
330
333
  return decoder.decode_string(subtype)
331
334
  elif major_type == 2:
332
335
  return decoder.decode_bytestring(subtype)
336
+ elif major_type == 7:
337
+ return decoder.decode_special(subtype)
333
338
  else:
334
339
  return major_decoders[major_type](decoder, subtype)
335
340
 
@@ -501,6 +506,24 @@ class JsonReceiver(TreeReceiver):
501
506
  return DiffEvent(event_type, concrete_type, msg)
502
507
 
503
508
 
509
+ def _decode_length(
510
+ decoder: CBORDecoder, subtype: int, allow_indefinite: bool = False
511
+ ) -> Optional[int]:
512
+ if subtype < 24:
513
+ return subtype
514
+ elif subtype == 24:
515
+ return decoder.read(1)[0]
516
+ elif subtype == 25:
517
+ return cast(int, struct.unpack(">H", decoder.read(2))[0])
518
+ elif subtype == 26:
519
+ return cast(int, struct.unpack(">L", decoder.read(4))[0])
520
+ elif subtype == 27:
521
+ return cast(int, struct.unpack(">Q", decoder.read(8))[0])
522
+ elif subtype == 31 and allow_indefinite:
523
+ return None
524
+ else:
525
+ raise CBORDecodeValueError(f"unknown unsigned integer subtype 0x{subtype:x}")
526
+
504
527
  class ParseErrorReceiver(Receiver):
505
528
  def fork(self, ctx):
506
529
  return ctx.fork(self.Visitor(), self.Factory())
@@ -292,13 +292,17 @@ class RemotingMessenger:
292
292
 
293
293
  def send_tree(
294
294
  self,
295
- sock: Union[BinaryIO, socket.socket],
295
+ dest: Union[BinaryIO, socket.socket],
296
296
  after: Tree,
297
297
  before: Optional[Tree] = None,
298
298
  ):
299
299
  b = BytesIO()
300
300
  self._context.new_sender_context(b).send_any_tree(after, before)
301
- sock.sendall(dumps(b.getvalue()))
301
+ if isinstance(dest, socket.socket):
302
+ dest.sendall(dumps(b.getvalue()))
303
+ else:
304
+ b.seek(0)
305
+ dest.write(dumps(b.getvalue()))
302
306
 
303
307
  def receive_tree(
304
308
  self,
rewrite_remote/sender.py CHANGED
@@ -21,7 +21,6 @@ import cbor2
21
21
  from cbor2 import CBOREncoder
22
22
  from rewrite import Tree, Markers, Marker, ParseErrorVisitor, Cursor, Style
23
23
  from rewrite.visitor import TreeVisitor
24
- from rewrite.java import JavaType
25
24
 
26
25
  from rewrite_remote import remote_utils
27
26
  from rewrite_remote.event import *
@@ -419,16 +418,7 @@ class DefaultValueSerializer(ValueSerializer):
419
418
  elif isinstance(value, UUID):
420
419
  encoder.encode(value.bytes)
421
420
  elif isinstance(value, Enum):
422
- if isinstance(value, JavaType.Primitive):
423
- # FIXME implement type attribution support
424
- encoder.encode(
425
- [
426
- "org.openrewrite.java.tree.JavaType$Primitive",
427
- value.value,
428
- ]
429
- )
430
- else:
431
- encoder.encode(value.value)
421
+ encoder.encode(value.value)
432
422
  elif isinstance(value, Path):
433
423
  encoder.encode(str(value))
434
424
  elif isinstance(value, (list, set, tuple)):
rewrite_remote/server.py CHANGED
@@ -2,18 +2,15 @@
2
2
  import importlib
3
3
  import importlib.resources
4
4
  import os
5
- import select
6
5
  import socket
7
6
  import sys
8
7
  import time
9
8
  import traceback
10
9
  import zipfile
11
10
  from io import BytesIO, StringIO
12
- from pathlib import Path
13
- from typing import Any
14
- from typing import Optional
15
11
 
16
12
  import cbor2
13
+ import select
17
14
  from cbor2 import dumps
18
15
  from rewrite import (
19
16
  ParserInput,
@@ -22,7 +19,6 @@ from rewrite import (
22
19
  ParseError,
23
20
  Recipe,
24
21
  )
25
- from rewrite.java import J
26
22
  from rewrite.java.remote import *
27
23
  from rewrite.python import Py
28
24
  from rewrite.python.parser import PythonParserBuilder
@@ -30,14 +26,17 @@ from rewrite.python.remote.receiver import PythonReceiver
30
26
  from rewrite.python.remote.sender import PythonSender
31
27
 
32
28
  from rewrite_remote.handlers.hello_world_handler import hello_world_handler
29
+ from rewrite_remote.handlers.list_projects_handler import list_projects_handler
30
+ from rewrite_remote.handlers.parse_project_sources_handler import (
31
+ parse_project_sources_handler,
32
+ )
33
+ from rewrite_remote.handlers.project_helper import read_file_contents
33
34
  from rewrite_remote.handlers.recipe_install_handler import (
34
35
  recipe_install_handler,
35
36
  )
36
37
  from rewrite_remote.handlers.run_recipe_load_and_visitor_handler import (
37
38
  run_recipe_load_and_visitor_handler,
38
39
  )
39
- from rewrite_remote.handlers.list_projects_handler import list_projects_handler
40
-
41
40
  from rewrite_remote.receiver import ReceiverContext
42
41
  from rewrite_remote.remoting import (
43
42
  RemotePrinterFactory,
@@ -98,6 +97,7 @@ class Server:
98
97
  "recipe-install": recipe_install_handler,
99
98
  "run-recipe-load-and-visitor": run_recipe_load_and_visitor_handler,
100
99
  "list-projects": list_projects_handler,
100
+ "parse-project-sources": parse_project_sources_handler,
101
101
  },
102
102
  )
103
103
 
@@ -234,11 +234,6 @@ class Server:
234
234
  sock.sendall(response_stream.getvalue())
235
235
 
236
236
 
237
- def read_file_contents(path: str) -> StringIO:
238
- with open(path, "r", newline="", encoding="utf-8") as file:
239
- return StringIO(file.read())
240
-
241
-
242
237
  def read_data_from_zip() -> None:
243
238
  # Access the resource within the 'your_package.resources' package
244
239
  # 'data.zip' is the name of the file included
@@ -1,8 +1,9 @@
1
+ import importlib
1
2
  import typing
2
- from typing import Optional
3
3
  from dataclasses import Field
4
4
  from functools import lru_cache
5
5
  from typing import Any, Type
6
+ from typing import Optional
6
7
 
7
8
 
8
9
  def to_java_type_name_from_value(v: Any) -> Optional[str]:
@@ -106,4 +107,7 @@ def __convert_snake_to_camel(field_name: str) -> str:
106
107
 
107
108
 
108
109
  def get_type(type_name: str) -> Type[Any]:
109
- raise NotImplementedError("get_type for: " + type_name)
110
+ # `type_name` will look like `org.openrewrite.java.tree.J$CompilationUnit`
111
+ parts = type_name.split('.')
112
+ module = importlib.import_module('rewrite.' + parts[2])
113
+ return getattr(module, parts[-1].split('$')[1])
@@ -1,23 +0,0 @@
1
- rewrite_remote/__init__.py,sha256=gl4Dpp7mYIrfNgeyh2IeW2fsj9ep9pveAK_eeoDLu7c,278
2
- rewrite_remote/client.py,sha256=95ZCAtVOngF0ZqqKnOsrweUeGKruf3UKGPXNGTrNyy0,1853
3
- rewrite_remote/event.py,sha256=texLJD1mcFkpBpiXAa-Rmip0Tgqm2OlBpRPHFZyWcBs,359
4
- rewrite_remote/receiver.py,sha256=64AQVCMGF7TQKA--n5bDMn1ZUalBrpOmfWBrAA_vA2k,19872
5
- rewrite_remote/remote_utils.py,sha256=gU9hN-aHxy9NF4uRqjd4OhvgPrNfDyCt3y1PtrWMCgA,10677
6
- rewrite_remote/remoting.py,sha256=bjZbikbOy7xAZGvWuPr0ceZA8qP5Hbr67JRp-3_6Jx0,13397
7
- rewrite_remote/sender.py,sha256=ezVUrDr3ZTwa-tZ-1jS2pRRQcPVcqMFigmoC69Omduw,19365
8
- rewrite_remote/server.py,sha256=g_-6_n7Y1hsVlTRbXZyl9Ywiabje12a0eT0X8hBc0xg,9473
9
- rewrite_remote/type_utils.py,sha256=oVrB0olWFSCqhmg2nTU2wrwiAU7kBCUscjwdHK7gf3Y,4219
10
- rewrite_remote/handlers/__init__.py,sha256=ED6jHcYiuYpr_0vjGz0zx2lrrmJT9sDJCzIljoDfmlM,65
11
- rewrite_remote/handlers/handler_helpers.py,sha256=xvAKAVGH56Hrjp9sbilp4v1a2_ra0L63YjXurF5K5o0,512
12
- rewrite_remote/handlers/hello_world_handler.py,sha256=NQScHfCJKofdImBgELL8tXtG_KnVyXj683C3Ae7xcKU,1298
13
- rewrite_remote/handlers/list_projects_handler.py,sha256=ukkCST7whpCxQ0omCWWw9W27Su3rFSnnEIhAS6T4iOU,2007
14
- rewrite_remote/handlers/project_helper.py,sha256=ldH47al5KDWb974uXcXF6WLZeZqAghKkcwjGAWBXrHs,7059
15
- rewrite_remote/handlers/pypi_manager.py,sha256=PwYIEocA9YNGgB7ZzzyzZFAb5GKJ1xPSZdSFvz1oZvg,10247
16
- rewrite_remote/handlers/recipe_install_handler.py,sha256=SsY7oXEJqE3mKUM_msnV0i-aUXmeUWpYjq_121ui3Z8,4920
17
- rewrite_remote/handlers/run_recipe_load_and_visitor_handler.py,sha256=BmsKjV38LenewWvun8cknGk_oR3GoinmmsXtWKUWUak,4085
18
- rewrite_remote/handlers/types.py,sha256=5TK_oFp-7iy1iACWisuQJsa_WHTsqcPrV9nQTZ-_xgo,518
19
- openrewrite_remote-0.13.5.dist-info/METADATA,sha256=Y43JgSirWSgWYfwvGTg9gbSPohfAfyyeuYHlCehRtkk,386
20
- openrewrite_remote-0.13.5.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
21
- openrewrite_remote-0.13.5.dist-info/entry_points.txt,sha256=SMukuF7TPjQr3IZIcH8f98-_QBCqYSbYXYrVv-5UzRI,69
22
- openrewrite_remote-0.13.5.dist-info/top_level.txt,sha256=ansTioSZ-62aH3F2L3d1Bua0pJF4GOtgQ1PpG-CzcP0,15
23
- openrewrite_remote-0.13.5.dist-info/RECORD,,