Skip to content

Commit

Permalink
Merge pull request #666 from intersystems/export-production
Browse files Browse the repository at this point in the history
Add export production option to menu for productions
  • Loading branch information
isc-tleavitt authored Dec 12, 2024
2 parents c87d2e7 + 4ed33dd commit 76221f9
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 35 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.9.0] - Unreleased

### Added
- Menu option to export production to support migrating to production decomposition (#665)

## [2.8.0] - 2024-12-06

### Added
Expand Down
7 changes: 6 additions & 1 deletion cls/SourceControl/Git/Extension.cls
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ XData Menu
<MenuItem Name="SwitchBranch" Save="101" />
<MenuItem Separator="true"/>
<MenuItem Name="ExportSystemDefaults" />
<MenuItem Name="ExportProduction" />
<MenuItem Name="Export" Save="101" />
<MenuItem Name="ExportForce" Save="101" />
<MenuItem Name="Import" />
Expand Down Expand Up @@ -148,6 +149,7 @@ Method LocalizeName(name As %String) As %String
"Fetch":$$$Text("@Fetch@Fetch from remote"),
"Pull":$$$Text("@Pull@Pull changes from remote branch"),
"Status": $$$Text("@Status@Status"),
"ExportProduction": $$$Text("@ExportProduction@Export Production"),
:name)
}

Expand All @@ -163,7 +165,7 @@ Method OnSourceMenuItem(name As %String, ByRef Enabled As %String, ByRef Display
}
if ##class(SourceControl.Git.Utils).IsNamespaceInGit() {

if $listfind($listbuild("AddToSC", "RemoveFromSC", "Revert", "Commit"), name) {
if $listfind($listbuild("AddToSC", "RemoveFromSC", "Revert", "Commit", "ExportProduction"), name) {
quit ..OnSourceMenuContextItem(InternalName,name,.Enabled,.DisplayName)
}

Expand Down Expand Up @@ -243,6 +245,9 @@ Method OnSourceMenuContextItem(itemName As %String, menuItemName As %String, ByR
if '(##class(SourceControl.Git.Change).IsUncommitted(##class(SourceControl.Git.Utils).FullExternalName(itemName))) || ($username '= userCheckedOut) {
set Enabled = 0
}
} elseif menuItemName = "ExportProduction" {
set itemNameNoExt = $piece(itemName,".",1,*-1)
set Enabled = (##class(SourceControl.Git.Production).IsProductionClass(itemNameNoExt,"FullExternalName"))
} elseif ##class(SourceControl.Git.Utils).IsInSourceControl(itemName) {
set Enabled = $case(menuItemName, "AddToSC":-1,:1)
} else {
Expand Down
66 changes: 35 additions & 31 deletions cls/SourceControl/Git/Util/Production.cls
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,40 @@ Include SourceControl.Git
Class SourceControl.Git.Util.Production
{

ClassMethod BaselineProduction(productionName, settings As SourceControl.Git.Settings = {##class(SourceControl.Git.Settings).%New()})
{
set productionInternalName = productionName _ ".cls"
if '##class(SourceControl.Git.Utils).FileIsMapped(productionInternalName) {
if settings.decomposeProductions {
write !, "Exporting production in decomposed format: " _ productionInternalName
if ##class(SourceControl.Git.Utils).IsInSourceControl(productionInternalName) {
set st = ##class(SourceControl.Git.Utils).RemoveFromSourceControl(productionInternalName)
$$$ThrowOnError(st)
}
set st = ##class(SourceControl.Git.Production).ExportProductionDefinitionShards(productionName,"FullExternalName",.itemInternalNames)
$$$ThrowOnError(st)
set key = $order(itemInternalNames(""))
while (key '= "") {
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(key)
$$$ThrowOnError(st)
set key = $order(itemInternalNames(key))
}
} else {
write !, "Exporting production in class format: " _ productionInternalName
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(productionInternalName)
$$$ThrowOnError(st)
set key = $order(@##class(SourceControl.Git.Utils).#Storage@("items", ""))
while (key '= "") {
if $match(key,"^"_productionName_"\|\|.*\.(?i)ptd$") {
set st = ##class(SourceControl.Git.Utils).RemoveFromSourceControl(key)
$$$ThrowOnError(st)
}
set key = $order(@##class(SourceControl.Git.Utils).#Storage@("items", key))
}
}
}
}

/// Baselines all productions in this namespace from single-file to decomposed or vice versa.
ClassMethod BaselineProductions()
{
Expand All @@ -13,37 +47,7 @@ ClassMethod BaselineProductions()
throw:rs.%SQLCODE<0 ##class(%Exception.SQL).CreateFromSQLCODE(rs.%SQLCODE,rs.%Message)
while rs.%Next(.sc) {
$$$ThrowOnError(sc)
set productionName = rs.Name
set productionInternalName = productionName _ ".cls"
if '##class(SourceControl.Git.Utils).FileIsMapped(productionInternalName) {
if settings.decomposeProductions {
write !, "Decomposing production: " _ productionInternalName
if ##class(SourceControl.Git.Utils).IsInSourceControl(productionInternalName) {
set st = ##class(SourceControl.Git.Utils).RemoveFromSourceControl(productionInternalName)
$$$ThrowOnError(st)
}
set st = ##class(SourceControl.Git.Production).ExportProductionDefinitionShards(productionName,"FullExternalName",.itemInternalNames)
$$$ThrowOnError(st)
set key = $order(itemInternalNames(""))
while (key '= "") {
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(key)
$$$ThrowOnError(st)
set key = $order(itemInternalNames(key))
}
} else {
write !, "Recomposing production: " _ productionInternalName
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(productionInternalName)
$$$ThrowOnError(st)
set key = $order(@##class(SourceControl.Git.Utils).#Storage@("items", ""))
while (key '= "") {
if $match(key,"^"_productionName_"\|\|.*\.(?i)ptd$") {
set st = ##class(SourceControl.Git.Utils).RemoveFromSourceControl(key)
$$$ThrowOnError(st)
}
set key = $order(@##class(SourceControl.Git.Utils).#Storage@("items", key))
}
}
}
do ..BaselineProduction(rs.Name, settings)
}
}

Expand Down
2 changes: 2 additions & 0 deletions cls/SourceControl/Git/Utils.cls
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
do ..RunGitCommand("status", .errStream, .outStream)
write !, !, "Git Status: "
do ..PrintStreams(outStream, errStream)
} elseif (menuItemName = "ExportProduction") {
do ##class(SourceControl.Git.Util.Production).BaselineProduction($piece(InternalName,".",1,*-1))
}
quit ec
}
Expand Down
2 changes: 1 addition & 1 deletion docs/production-decomposition.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Production Decomposition is a feature of Embedded Git that allows multiple devel
## Enabling production decomposition
The feature may be enabled by checking the "Decompose Productions" box in the Git Settings page. For deployment of changes to other environments through git to work properly, the value of this setting must match on all namespaces connected to this repository. To assist, settings are automatically exported into a `embedded-git-config.json` file at the root of the repository that may be committed and imported into other environments.

If there are existing productions in the namespace, they should be migrated to the new decomposed format by running `do ##class(SourceControl.Git.API).BaselineProductions()`. You may then use the Git Web UI to view, commit, and push the corresponding changes. This method should be run in a single namespace and then deployed to other namespaces through normal Embedded Git deployment mechanisms.
If there are existing productions in the namespace, they should be migrated to the new decomposed format. Do this by opening the production and selecting the "Export Production" option in the source control menu. You may then use the Git Web UI to view, commit, and push the corresponding changes. This step should be done in a single namespace and then deployed to other namespaces through normal Embedded Git deployment mechanisms.

## Editing productions in the IDE
There are a couple of limitations related to editing a production class directly in an integrated development environment (Studio or VS Code).
Expand Down
2 changes: 1 addition & 1 deletion docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ The following is a testing plan that should be followed prior to release of a ne
- Test migration of a production to decomposed format:
- On the initial namespace, disable production decomposition. Create a new production and add a number of items. Sync and confirm it has been pushed to the remote repository.
- On the second namespace, sync and confirm the new production has been created.
- On the initial namespace, turn on production decomposition. From terminal, run `do ##class(SourceControl.Git.API).BaselineProductions()`. Confirm the Web UI includes changes for delete of the old production class and adds for all production items. Commit all items and push the branch.
- On the initial namespace, turn on production decomposition. Open the production page and use the "Export Production" option in the source control menu. Confirm the Web UI includes changes for delete of the old production class and adds for all production items. Commit all items and push the branch.
- On the second namespace, turn on production decomposition. Sync. The production should be reloaded with no changes.
2 changes: 1 addition & 1 deletion module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<Document name="git-source-control.ZPM">
<Module>
<Name>git-source-control</Name>
<Version>2.8.0</Version>
<Version>2.9.0</Version>
<Description>Server-side source control extension for use of Git on InterSystems platforms</Description>
<Keywords>git source control studio vscode</Keywords>
<Packaging>module</Packaging>
Expand Down

0 comments on commit 76221f9

Please sign in to comment.