fix(git_init): default to sibling _git dir, auto-create, clear empty check
CODESYS Git uses a dual-storage model: the .project file stays where
it is, the git working tree lives in a SEPARATE empty directory. The
prior default ("init in the project's own folder") tripped over the
project file itself and CODESYS would raise the unhelpful
'gitProjectStoragePath: ... is not a valid Git repository location:
DirectoryNotEmpty'. Hit this end-to-end during the first PDE-Demo
smoke test on 2026-04-25 -- the user had to dance around it manually.
git_init now:
- Defaults LocalRepoPath to '<project_basename>_git' as a sibling of
the project's own dir when not supplied (or when supplied equal to
the project dir, which has the same trap).
- Auto-creates the target dir if missing.
- Pre-validates emptiness and raises a clear, action-oriented error
if non-empty, instead of letting CODESYS surface DirectoryNotEmpty.
server.ts tool description updated to call out the dual-storage rule
and the auto-default behaviour up front.
Verified API contract via Stubs/scriptengine/GitScriptProject.pyi
(local SP22 install) and the helpme-codesys.com Git scripting page
(https://content.helpme-codesys.com/en/CODESYS%20Git/_git_using_scripting.html).
This commit is contained in:
parent
3623c45d31
commit
31e842929e
2 changed files with 35 additions and 5 deletions
|
|
@ -19,9 +19,39 @@ try:
|
|||
"the project does not yet have a git binding. The init() "
|
||||
"call below should establish one if a repo path is supplied.")
|
||||
|
||||
if not LOCAL_REPO_PATH:
|
||||
# Default: init a repo in the project's own directory
|
||||
LOCAL_REPO_PATH = os.path.dirname(PROJECT_FILE_PATH)
|
||||
# CODESYS Git uses a dual-storage model: the .project file stays where it
|
||||
# is, the git working tree lives in a SEPARATE empty directory. Pointing
|
||||
# init() at the project's own folder fails with "DirectoryNotEmpty", and
|
||||
# passing nothing previously dumped the user into that trap. Default to a
|
||||
# '<project_basename>_git' sibling and auto-create it; verify it is empty
|
||||
# before handing off to CODESYS so we surface a clear hint instead of
|
||||
# CODESYS's lower-level error.
|
||||
project_dir = os.path.dirname(PROJECT_FILE_PATH)
|
||||
project_stem = os.path.splitext(os.path.basename(PROJECT_FILE_PATH))[0]
|
||||
if not LOCAL_REPO_PATH or os.path.normcase(os.path.abspath(LOCAL_REPO_PATH)) == os.path.normcase(os.path.abspath(project_dir)):
|
||||
if LOCAL_REPO_PATH:
|
||||
print("DEBUG: requested LocalRepoPath equals the project dir; "
|
||||
"rerouting to a sibling because CODESYS Git requires a separate empty dir.")
|
||||
# Use a sibling so we don't write into the (likely shared) project folder
|
||||
LOCAL_REPO_PATH = os.path.join(os.path.dirname(project_dir), project_stem + "_git")
|
||||
print("DEBUG: defaulted LocalRepoPath to '%s'" % LOCAL_REPO_PATH)
|
||||
|
||||
if not os.path.exists(LOCAL_REPO_PATH):
|
||||
print("DEBUG: creating LocalRepoPath '%s'" % LOCAL_REPO_PATH)
|
||||
os.makedirs(LOCAL_REPO_PATH)
|
||||
elif not os.path.isdir(LOCAL_REPO_PATH):
|
||||
raise RuntimeError(
|
||||
"LocalRepoPath '%s' exists but is not a directory." % LOCAL_REPO_PATH)
|
||||
else:
|
||||
existing = os.listdir(LOCAL_REPO_PATH)
|
||||
if existing:
|
||||
raise RuntimeError(
|
||||
"LocalRepoPath '%s' is not empty (contains %d entries: %s). "
|
||||
"CODESYS Git's dual-storage model requires a fresh empty "
|
||||
"directory separate from the project's own folder. Either "
|
||||
"pass a different localRepoPath or empty this one, then "
|
||||
"retry git_init." % (
|
||||
LOCAL_REPO_PATH, len(existing), existing[:5]))
|
||||
|
||||
print("DEBUG: calling git.init('%s')" % LOCAL_REPO_PATH)
|
||||
git.init(LOCAL_REPO_PATH)
|
||||
|
|
|
|||
|
|
@ -1066,10 +1066,10 @@ export async function startMcpServer(config: ServerConfig): Promise<void> {
|
|||
|
||||
s.tool(
|
||||
'git_init',
|
||||
"Initialises a Git repository for the project's directory (or a custom path) via project.git.init(). One-shot setup; use git_status afterwards to confirm. Requires the CODESYS Git plug-in AND an active CODESYS Professional Developer Edition subscription license -- without the subscription, the tool fails fast with a clear PDE-required message (the runtime 'HasGitLicense' rule gates every project.git.* call).",
|
||||
"Initialises a Git working tree for the project via project.git.init(). CODESYS Git uses a dual-storage model: the .project file stays where it is, the git repo lives in a SEPARATE empty directory. If localRepoPath is omitted (or equals the project's own folder), the tool auto-defaults to a '<project_basename>_git' sibling and auto-creates it; if it exists and is non-empty, the tool fails with a clear hint. One-shot setup; use git_status afterwards to confirm. Requires the CODESYS Git plug-in AND an active CODESYS Professional Developer Edition subscription license -- without the subscription, the tool fails fast with a clear PDE-required message (the runtime 'HasGitLicense' rule gates every project.git.* call).",
|
||||
{
|
||||
projectFilePath: z.string().describe("Path to the project file."),
|
||||
localRepoPath: z.string().optional().describe("Filesystem path to initialise the repo at. Defaults to the project file's parent directory."),
|
||||
localRepoPath: z.string().optional().describe("Filesystem path for the git working tree. Must be a separate empty directory, NOT the project's own folder. If omitted, defaults to a '<project_basename>_git' sibling and auto-creates it."),
|
||||
},
|
||||
async (args: { projectFilePath: string; localRepoPath?: string }) => {
|
||||
const escaped = resolvePath(args.projectFilePath, workspaceDir);
|
||||
|
|
|
|||
Loading…
Reference in a new issue