Skip to content

Commit

Permalink
update routes when routes folder's files were changed
Browse files Browse the repository at this point in the history
  • Loading branch information
absszero committed Oct 20, 2023
1 parent 13a7b30 commit 7b73365
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 42 deletions.
14 changes: 9 additions & 5 deletions lib/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ def __init__(self, console_kernel=None):
if self.console_kernel:
return
for folder in workspace.get_folders():
fullpath = workspace.get_path(
folder,
'app/Console/Kernel.php',
True
)
fullpath = workspace.get_path(folder, 'app/Console/Kernel.php')
if not fullpath:
continue

Expand All @@ -40,6 +36,9 @@ def get_command_signature(self, content):
return ''

def collect_files(self):
'''
collect command files from $this->load(__DIR__)
'''
files = []
match = re.search(
r"""function commands\([^\)]*[^{]+([^}]+)""",
Expand Down Expand Up @@ -70,6 +69,11 @@ def collect_file_cmds(self, files):
return commands

def collect_registered_cmds(self):
'''
collect commands from $command = [
]
'''
commands = {}
match = re.search(
r"""\$commands\s*=\s*\[([^\]]+)""",
Expand Down
2 changes: 1 addition & 1 deletion lib/finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def get_place(selection):
component_place,
middleware_place,
command_place,
# route_place,
route_place,
controller_place,
)

Expand Down
3 changes: 3 additions & 0 deletions lib/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def all(self):
return middlewares

def collect_classnames(self, content):
'''
collect class aliases
'''
classnames = {}
pattern = re.compile(r"use\s+([^\s]+)\s+as+\s+([^;]+)")
for match in pattern.findall(content):
Expand Down
33 changes: 20 additions & 13 deletions lib/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,31 @@
import json
from .setting import Setting

routes = {}


class Router:
def __init__(self):
for folder in workspace.get_folders():
self.artisan = workspace.get_path(
folder,
'artisan',
True
)
if self.artisan:
self.artisan = workspace.get_path(folder, 'artisan')
self.dir = workspace.get_folder_path(folder, 'routes')
if self.dir:
return

def all(self):
routes = {}
if not self.artisan:
return routes
def update(self, filepath=None):
'''
update routes if routes folder's files were changed
'''
if not self.artisan or not self.dir:
return

if not workspace.is_changed(self.dir, filepath):
return
workspace.set_unchange(self.dir)

php = Setting().get('php_bin')
if not php:
return routes
return

args = [
php,
Expand All @@ -36,13 +41,13 @@ def all(self):
try:
output = subprocess.check_output(args, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError:
return routes
return

output = output.decode('utf-8')
try:
route_rows = json.loads(output)
except ValueError:
return routes
return

for route_row in route_rows:
if 'Closure' == route_row['action']:
Expand All @@ -55,4 +60,6 @@ def all(self):
location=action
)

def all(self):
self.update()
return routes
98 changes: 85 additions & 13 deletions lib/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,54 @@

mTimes = {}
contents = {}
changes = {}


def get_file_content(folder, filepath=None):
fullpath = folder
if filepath:
fullpath = get_path(folder, filepath, True)
def is_changed(folder_path, file_path=None):
'''
is the folder's files were changed
:param file_path only check the file in the folder
'''

if file_path:
if not file_path.startswith(folder_path):
return False

mTime = os.path.getmtime(file_path)
return mTimes.get(file_path) != mTime

if folder_path not in changes:
return True
files = os.listdir(folder_path)
if changes[folder_path] != len(files):
return True
for file in files:
fullpath = os.path.join(folder_path, file)
mTime = os.path.getmtime(fullpath)
if mTimes.get(fullpath) != mTime:
return True

return False


def set_unchange(folder_path):
'''
set the folder's files is changed
'''

files = os.listdir(folder_path)
changes[folder_path] = len(files)

for file in files:
fullpath = os.path.join(folder_path, file)
mTime = os.path.getmtime(fullpath)
mTimes[fullpath] = mTime


def get_file_content(base, file_path=None):
fullpath = base
if file_path:
fullpath = get_path(base, file_path)
if not fullpath:
return
if not os.path.isfile(fullpath):
Expand All @@ -28,6 +70,9 @@ def get_file_content(folder, filepath=None):


def get_recursion_files(folder, ext='.php'):
'''
get all files including sub-dirs with the extension
'''
files = []
for folder, subfolders, filenames in os.walk(folder):
for filename in filenames:
Expand All @@ -36,31 +81,55 @@ def get_recursion_files(folder, ext='.php'):
return files


def get_path(folder, filepath, recursion=False):
def get_folder_path(base, folder_name, recursion=True):
'''
get real path by folder name
'''
files = os.listdir(base)
if folder_name in files:
return os.path.join(base, folder_name)

if not recursion:
return

for file in files:
folder = os.path.join(base + '/' + file)
if not os.path.isdir(folder):
continue

fullpath = get_folder_path(folder, folder_name, False)
if fullpath:
return fullpath


def get_path(base, file_path, recursion=True):
'''
get real path by a part of file path
'''
top_dir = None
if '/' in filepath:
top_dir = filepath.split('/')[0]
if '/' in file_path:
top_dir = file_path.split('/')[0]

files = os.listdir(folder)
if not top_dir and filepath in files:
fullpath = os.path.join(folder, filepath)
files = os.listdir(base)
if not top_dir and file_path in files:
fullpath = os.path.join(base, file_path)
if os.path.isfile(fullpath):
return fullpath
return None

for file in files:
if os.path.isdir(folder + '/' + file) is False:
if os.path.isdir(base + '/' + file) is False:
continue

# if not the right dictionary, search the sub dictionaries
if top_dir != file:
if recursion:
fullpath = get_path(folder + '/' + file, filepath)
fullpath = get_path(base + '/' + file, file_path, False)
if fullpath:
return fullpath
continue

fullpath = os.path.join(folder, filepath)
fullpath = os.path.join(base, file_path)
if os.path.isfile(fullpath):
return fullpath

Expand All @@ -70,6 +139,9 @@ def get_folders():


def class_2_file(class_name):
'''
convert PHP class name to filename
'''
class_name = class_name
filename = class_name.replace(',', '').replace('::class', '')
filename = filename.replace('\\', '/').strip() + '.php'
Expand Down
4 changes: 4 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from .lib.selection import Selection
from .lib.finder import get_place
from .lib.setting import Setting
from .lib.router import Router

place = None

Expand All @@ -42,6 +43,9 @@ def on_activated(self, view):
view.show(location)
place = None

def on_post_save_async(self, view):
Router().update(view.file_name())

def on_hover(self, view, point, hover_zone):
if view.is_popup_visible():
return
Expand Down
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Route::resource('photo', 'HelloController', ['only' => [
]]);
```

### Go to Controller from route helper

![](route.gif)

### Go to Middleware

![](middleware.gif)
Expand Down
Binary file added route.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 19 additions & 4 deletions tests/test_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,29 @@

class TestRouter(unittest.ViewTestCase):
@patch('subprocess.check_output')
@patch('LaravelGoto.lib.workspace.set_unchange')
@patch('LaravelGoto.lib.workspace.is_changed')
@patch('LaravelGoto.lib.workspace.get_path')
@patch('LaravelGoto.lib.workspace.get_folder_path')
@patch('LaravelGoto.lib.workspace.get_folders')
def test_all(self, mock_get_folders, mock_get_path, mock_check_output):
mock_get_folders.return_value = [self.get_test_dir()]
mock_get_path.return_value = 'artisan'
mock_check_output.return_value = bytes('[{"name":"admin.index","action":"App\\\\Http\\\\Controllers\\\\AdminController@index","middleware":[]},{"name":null,"action":"Closure","middleware":[]},{"name":null,"action":"Closure","middleware":[]}]', 'utf-8') # noqa: E501
def test_all(
self,
m_get_folders,
m_get_folder_path,
m_get_path,
m_is_changed,
m_set_unchange,
m_check_output
):
m_get_folders.return_value = [self.get_test_dir()]
m_get_folder_path.return_value = 'dir'
m_get_path.return_value = 'artisan'
m_is_changed.return_value = True
m_set_unchange.return_value = None
m_check_output.return_value = bytes('[{"name":"admin.index","action":"App\\\\Http\\\\Controllers\\\\AdminController@index","middleware":[]},{"name":null,"action":"Closure","middleware":[]},{"name":null,"action":"Closure","middleware":[]}]', 'utf-8') # noqa: E501

router = Router()
router.update()
routes = router.all()

self.assertEqual(
Expand Down
30 changes: 24 additions & 6 deletions tests/test_workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,15 @@ def test_get_file_content(self):
content.__contains__('class Kernel extends HttpKernel')
)

content = workspace.get_file_content(__file__)
self.assertTrue(content.__contains__('TestWorkspace'))

def test_get_path(self):
folder = os.path.dirname(os.path.abspath(__file__))
fullpapth = workspace.get_path(folder, 'app/Http/Kernel.php', True)
fullpapth = workspace.get_path(folder, 'app/Http/Kernel.php')
self.assertTrue(fullpapth.__contains__('app/Http/Kernel.php'))

fullpapth = workspace.get_path(folder, 'unittest.py', True)
fullpapth = workspace.get_path(folder, 'unittest.py')
self.assertTrue(fullpapth.__contains__('unittest.py'))

fullpapth = workspace.get_path(folder, 'sample.php', True)
fullpapth = workspace.get_path(folder, 'sample.php')
self.assertTrue(fullpapth.__contains__('sample.php'))

def test_get_recursion_files(self):
Expand All @@ -38,3 +35,24 @@ def test_get_recursion_files(self):
def test_class_2_file(self):
filename = workspace.class_2_file("\\App\\NS\\SayGoodbye::class,")
self.assertEqual(filename, 'app/NS/SayGoodbye.php')

def test_get_folder_path(self):
base = os.path.dirname(os.path.abspath(__file__))

path = workspace.get_folder_path(base, 'fixtures')
self.assertTrue(path.endswith('fixtures'), path)

path = workspace.get_folder_path(base, 'config')
self.assertTrue(path.endswith('config'), path)

path = workspace.get_folder_path(base, 'Http')
self.assertFalse(path)

def test_changed(self):
base = os.path.dirname(os.path.abspath(__file__))
self.assertTrue(workspace.is_changed(base))
self.assertTrue(workspace.is_changed(base, __file__))
self.assertFalse(workspace.is_changed(base, '/aaa/bbb'))
workspace.set_unchange(base)
self.assertFalse(workspace.is_changed(base), 'post')
self.assertFalse(workspace.is_changed(base, __file__))

0 comments on commit 7b73365

Please sign in to comment.