Skip to content

Commit

Permalink
Build phase (MethodsAndPractices#171)
Browse files Browse the repository at this point in the history
Separated the formats and types into individual files. Then added a build script to merge into single files for deployment. This makes the final module smaller and load faster.
  • Loading branch information
DarqueWarrior authored Jul 4, 2019
1 parent db80b54 commit 0a7cd90
Show file tree
Hide file tree
Showing 247 changed files with 7,421 additions and 9,784 deletions.
Binary file added .DS_Store
Binary file not shown.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,11 @@ integration/prime.ps1
.vs/slnx.sqlite
unit/results.xml
en-US/VSTeam-Help.xml
Source/Classes/classes.ps1
Source/formats/formats.ps1xml
Source/types/vsteam.types.ps1xml
Source/formats/vsteam.format.ps1xml
Source/Public/vsteam.public.ps1
Source/Private/vsteam.private.ps1
Source/Classes/vsteam.classes.ps1
/dist
55 changes: 55 additions & 0 deletions Build-Module.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[CmdletBinding()]
param(
[string]$outputDir = './dist',

# Building help is skipped by default to speed your inner loop.
# Use this flag to include building the help
[switch]$buildHelp,

# By default the build will not install dependencies
[switch]$installDep
)

. ./Merge-File.ps1

if ($installDep.IsPresent) {
# Load the psd1 file so you can read the required modules and install them
$manifest = Import-PowerShellDataFile .\Source\VSTeam.psd1

# Install each module
$manifest.RequiredModules | ForEach-Object { if (-not (get-module $_ -ListAvailable)) { Write-Host "Installing $_"; Install-Module -Name $_ -Repository PSGallery -F -Scope CurrentUser } }
}

if ([System.IO.Path]::IsPathRooted($outputDir)) {
$output = $outputDir
}
else {
$output = Join-Path (Get-Location) $outputDir
}

Merge-File -inputFile ./Source/_functions.json -outputDir $output
Merge-File -inputFile ./Source/types/_types.json -outputDir $output
Merge-File -inputFile ./Source/Classes/_classes.json -outputDir $output
Merge-File -inputFile ./Source/formats/_formats.json -outputDir $output

# Build the help
if ($buildHelp.IsPresent) {
Write-Output 'Creating help files'
Push-Location
Set-Location ./.docs
./gen-help.ps1
Pop-Location
}

Write-Output 'Publishing help files'
Copy-Item -Path ./Source/en-US -Destination "$output/" -Recurse -Force
Copy-Item -Path ./Source/VSTeam.psm1 -Destination "$output/VSTeam.psm1" -Force

Write-Output 'Updating Functions To Export'
$newValue = ((Get-ChildItem -Path "./Source/Public" -Filter '*.ps1').BaseName |
ForEach-Object -Process { Write-Output "'$_'" }) -join ','

(Get-Content "./Source/VSTeam.psd1") -Replace ("FunctionsToExport.+", "FunctionsToExport = ($newValue)") |
Set-Content "$output/VSTeam.psd1"

Write-Output "Publish complete to $output"
206 changes: 206 additions & 0 deletions Merge-File.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
function Merge-File {
<#
.SYNOPSIS
Combines all the files in the provided inputFile into a single file.
.DESCRIPTION
The input file must be a JSON file in the following format:
{
output: "outputFileName.ps1",
files: ["file1.ps1", "file2.ps1"]
}
All the files are read and any using statements removed. All the
removed using statements are collected and written at the top of the
output file. All comments will also be removed from the output file.
.PARAMETER InputFile
The JSON file to process.
.PARAMETER outputDir
The destination folder.
.EXAMPLE
PS C:\> Merge-File -InputFile .\Source\Classes\classes.json
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)]
[string]
$inputFile,

[Parameter(Mandatory = $True)]
[string]
$outputDir
)

$fullPath = $(Resolve-Path $inputFile)
Write-Verbose "Full Path: $fullPath"

$fileOrder = Get-Content $fullPath -Raw | ConvertFrom-Json
Write-Output "Processing: $($fileOrder.fileType) in $fullPath"

$workingDir = Split-Path $fullPath
Write-Verbose "Working Directory: $workingDir"

$output = Join-Path $outputDir $fileOrder.outputFile

Push-Location
Set-Location $workingDir

try {
$files = $()

foreach ($file in $fileOrder.files) {
foreach ($item in $(Get-ChildItem -Filter $file)) {
$files += , (Resolve-Path $item.FullName)
}
}

# This makes sure the file is there and empty.
# If the file already exisit it will be overwritten.
$null = New-Item -ItemType file -Path $output -Force
Write-Output "Creating: $output"

switch ($fileOrder.fileType) {
'formats' {
Merge-Format $files | Add-Content $output
}
'types' {
Merge-Type $files | Add-Content $output
}
'functions' {
Merge-Function $files | Add-Content $output
}
Default {
Merge-Class $files | Add-Content $output
}
}
}
catch {
throw $_
}
finally {
Pop-Location
}
}

function Merge-Format {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)]
[string[]]
$files
)

process {
$finalXml = '<?xml version="1.0" encoding="utf-8" ?><Configuration><ViewDefinitions>'

ForEach ($file in $files) {
Write-Verbose -Message "Merging from $file"
$fileContents = Get-Content $file
$newFileContents = ($fileContents -replace '<!--.+-->', '')
[xml]$xml = $newFileContents

$finalXml += $xml.Configuration.ViewDefinitions.InnerXml
}

$finalXml += '</ViewDefinitions></Configuration>'

Write-Output ([xml]$finalXml).OuterXml
}
}

function Merge-Type {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)]
[string[]]
$files
)

process {
$finalXml = '<?xml version="1.0" encoding="utf-8" ?><Types>'

ForEach ($file in $files) {
Write-Verbose -Message "Merging from $file"
$fileContents = Get-Content $file
$newFileContents = ($fileContents -replace '<!--.+-->', '')
[xml]$xml = $newFileContents

$finalXml += $xml.Types.InnerXml
}

$finalXml += '</Types>'

Write-Output ([xml]$finalXml).OuterXml
}
}

function Merge-Function {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)]
[string[]]
$files
)

process {
$contents = New-Object System.Text.StringBuilder

ForEach ($file in $files) {
Write-Verbose -Message "Merging from $file"
$fileContents = Get-Content $file

foreach ($line in $fileContents) {
$contents.AppendLine($line) | Out-Null
}
}

Write-Output $contents.ToString()
}
}

function Merge-Class {
[CmdletBinding()]
param(
[Parameter(Mandatory = $True)]
[string[]]
$files
)

process {
$usingsSb = New-Object System.Text.StringBuilder
$contents = New-Object System.Text.StringBuilder

ForEach ($file in $files) {
Write-Verbose -Message "Merging from $file"
$fileContents = Get-Content $file

# Find all the usings and save them
$matches = $fileContents | Select-String 'using.+'

ForEach ($m in $matches) {
Write-Verbose "Found $($m.Line)"

# Don't add duplicate usings
if ($null -eq ($usings | Where-Object { $_ -eq $m.Line })) {
$usingsSb.AppendLine($m.Line) | Out-Null
$usings += , $m.Line
}
}

# Remove move all the using statements and comments
$newFileContents = ($fileContents -replace 'using.+', '')
$newFileContents = ($newFileContents -replace '#.+', '')
foreach ($line in $newFileContents) {
if ($null -ne $line.Trim() -and '' -ne $line.Trim()) {
$contents.AppendLine($line) | Out-Null
}
}
}

Write-Output "$($usingsSb.ToString()) $($contents.ToString())"
}
}
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,30 @@ During the release the module is installed on macOS, Linux and Window and tested
## Module Dependencies

- [SHiPS module](https://www.powershellgallery.com/packages/SHiPS/)
- [Trackyon.Utils module](https://www.powershellgallery.com/packages/Trackyon.Utils)

## Building Module

In an effort to reduce the module size this repository contains two scripts Build-Module.ps1 and Merge-File.ps1 that merges similar files into a single file. The files in the formats folder are merged into vsteam.format.ps1xml. The files in the classes folder are merged into vsteam.classes.ps1. The functions from the Private and Public folders are merged into vsteam.functions.ps1. Finally all the files in the types folder are merged into vsteam.types.ps1xml. The order of the files being merged can be controlled by the _*.json files in the repository.

The JSON files must be in the following format:

```JSON
{
"outputFile": "vsteam.functions.ps1",
"fileType": "functions",
"files": [
"./Private/*.ps1",
"./Public/*.ps1"
]
}
```

The final module is stored in a dist folder by default. You can override this folder by using the -outputDir parameter to the Build-Module.ps1 script.

To generate the help add the -buildHelp switch parameter.

You can also use the -installDep switch parameter to install all the module dependencies to bootstrap your development.

## Contributors

Expand Down
5 changes: 4 additions & 1 deletion Source/Classes/VSTeamRelease.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ class VSTeamRelease : VSTeamDirectory {
$this.DefinitionName = $obj.releaseDefinition.name
$this.CreatedBy = [VSTeamUserEntitlement]::new($obj.createdBy, $ProjectName)
$this.ModifiedBy = [VSTeamUserEntitlement]::new($obj.modifiedBy, $ProjectName)
$this.RequestedFor = [VSTeamUserEntitlement]::new($obj.requestedFor, $ProjectName)

if ($obj.PSObject.Properties.Match('RequestedFor').count -gt 0) {
$this.RequestedFor = [VSTeamUserEntitlement]::new($obj.requestedFor, $ProjectName)
}

$this._internalObj = $obj

Expand Down
54 changes: 54 additions & 0 deletions Source/Classes/_classes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"outputFile": "vsteam.classes.ps1",
"fileType": "classes",
"files": [
"VSTeamVersions.ps1",
"VSTeamProjectCache.ps1",
"VSTeamProcessCache.ps1",
"VSTeamDirectory.ps1",
"VSTeamLeaf.ps1",
"VSTeamPools.ps1",
"VSTeamInstallState.ps1",
"VSTeamExtensions.ps1",
"VSTeamFeeds.ps1",
"VSTeamAgent.ps1",
"VSTeamTask.ps1",
"VSTeamAttempt.ps1",
"VSTeamUserEntitlement.ps1",
"VSTeamPool.ps1",
"VSTeamQueue.ps1",
"VSTeamEnvironment.ps1",
"VSTeamRelease.ps1",
"VSTeamReleases.ps1",
"VSTeamBuild.ps1",
"VSTeamBuildDefinitions.ps1",
"VSTeamBuilds.ps1",
"VSTeamQueues.ps1",
"VSTeamRepositories.ps1",
"VSTeamTeams.ps1",
"VSTeamProject.ps1",
"VSTeamGitRepository.ps1",
"VSTeamBuildDefinitionProcessPhaseStep.ps1",
"VSTeamBuildDefinitionProcessPhase.ps1",
"VSTeamBuildDefinitionProcess.ps1",
"VSTeamBuildDefinition.ps1",
"VSTeamExtension.ps1",
"VSTeamFeed.ps1",
"VSTeamProcess.ps1",
"VSTeamRef.ps1",
"VSTeamTeam.ps1",
"VSTeamAccount.ps1",
"VSTeamGitRepositoryPermissions.ps1",
"VSTeamIdentityPermissions.ps1",
"VSTeamProjectPermissions.ps1",
"VSTeamWorkItemAreaPermissions.ps1",
"VSTeamWorkItemIterationPermissions.ps1",
"VSTeamGroup.ps1",
"VSTeamDescriptor.ps1",
"VSTeamSecurityNamespace.ps1",
"VSTeamAccessControlEntry.ps1",
"VSTeamAccessControlList.ps1",
"VSTeamUser.ps1",
"VSTeamClassificationNode.ps1"
]
}
Loading

0 comments on commit 0a7cd90

Please sign in to comment.