Skip to content

Commit

Permalink
a few lints
Browse files Browse the repository at this point in the history
  • Loading branch information
KnicKnic committed Jul 11, 2019
1 parent fab732d commit 848c2b7
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 26 deletions.
2 changes: 1 addition & 1 deletion native-powershell
4 changes: 2 additions & 2 deletions pkg/powershell/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ All objects that you create or are returned to you must be Closed by you. There
Multithreading
A single runspace is not multithreaded, do not try this! Objects generated in one runspace can be used in another assuming there is proper .Net concurrent access to those objects.
A single runspace is not multithreaded, do not try this! Objects generated in one runspace can be used in another assuming there is proper .Net concurrent access to those objects.
Reentrancy
Expand All @@ -25,7 +25,7 @@ Runspaces
A runspace is where you execute your powershell commands and statements in. It is also a boundary for variables such as "$global". If you specify custom log routines or callback handlers they are also bound to the runspace. This is to enable you to bind context to the log routine or callback handler.
Please see the runspace section for more information on creating a runspace and executing scripts and commands https://godoc.org/github.com/KnicKnic/go-powershell/pkg/powershell#Runspace .
Please see the runspace section for more information on creating a runspace and executing scripts and commands https://godoc.org/github.com/KnicKnic/go-powershell/pkg/powershell#Runspace .
Scripts vs Commands
Expand Down
8 changes: 4 additions & 4 deletions pkg/powershell/higherops.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,24 @@ func (runspace Runspace) ExecCommand(commandStr string, useLocalScope bool, name
return processArgs(command, false, namedArgs, args...)
}

// ExecScriptJsonMarshallUnknown - executes a series of statements (not to be confused with .ps1 files which are commands) in powershell
// ExecScriptJSONMarshalUnknown - executes a series of statements (not to be confused with .ps1 files which are commands) in powershell
//
// useLocalScope - true means to create a child scope, false means to use the global scope (this is probably what you want)
//
// Although namedArgs and args both state that they take interface, string and Object (a result from a previous powershell invocation) will get sent to powershell directly. Any other type will first get marshaled to json using json.Marshal and sent as a string to powershell
func (runspace Runspace) ExecScriptJsonMarshalUnknown(commandStr string, useLocalScope bool, namedArgs map[string]interface{}, args ...interface{}) *InvokeResults {
func (runspace Runspace) ExecScriptJSONMarshalUnknown(commandStr string, useLocalScope bool, namedArgs map[string]interface{}, args ...interface{}) *InvokeResults {
command := runspace.createCommand()
defer command.Close()
command.AddScript(commandStr, useLocalScope)
return processArgs(command, true, namedArgs, args...)
}

// ExecCommandJsonMarshalUnknown - executes a command (cmdlets, command files (.ps1), functions, ...) in powershell
// ExecCommandJSONMarshalUnknown - executes a command (cmdlets, command files (.ps1), functions, ...) in powershell
//
// useLocalScope - true means to create a child scope, false means to use the global scope (this is probably what you want)
//
// Although namedArgs and args both state that they take interface, string and Object (a result from a previous powershell invocation) will get sent to powershell directly. Any other type will first get marshaled to json using json.Marshal and sent as a string to powershell
func (runspace Runspace) ExecCommandJsonMarshalUnknown(commandStr string, useLocalScope bool, namedArgs map[string]interface{}, args ...interface{}) *InvokeResults {
func (runspace Runspace) ExecCommandJSONMarshalUnknown(commandStr string, useLocalScope bool, namedArgs map[string]interface{}, args ...interface{}) *InvokeResults {
command := runspace.createCommand()
defer command.Close()
command.AddCommand(commandStr, useLocalScope)
Expand Down
6 changes: 3 additions & 3 deletions pkg/powershell/higherops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ func TestCpowershellCommandArgumentTypePanic(t *testing.T) {
}
}
}()
results := runspace.ExecCommandJsonMarshalUnknown("Get-ItemPropertyValue", true, map[string]interface{}{
results := runspace.ExecCommandJSONMarshalUnknown("Get-ItemPropertyValue", true, map[string]interface{}{
"Name": jsonMarshalFailure{"2"},
})
defer results.Close()
Expand All @@ -390,7 +390,7 @@ func TestCpowershellCommandArgumentTypePanic(t *testing.T) {
}
}
}()
results := runspace.ExecScriptJsonMarshalUnknown("Get-ItemPropertyValue", true, nil, jsonMarshalFailure{"3"})
results := runspace.ExecScriptJSONMarshalUnknown("Get-ItemPropertyValue", true, nil, jsonMarshalFailure{"3"})
defer results.Close()
}()
if !caughtUnknownArgumentType {
Expand All @@ -407,7 +407,7 @@ func TestCpowershellJsonMarshal(t *testing.T) {
// auto cleanup your runspace
defer runspace.Close()

paramResults := runspace.ExecCommandJsonMarshalUnknown(`Write-Host`, true, map[string]interface{}{"Object": 17})
paramResults := runspace.ExecCommandJSONMarshalUnknown(`Write-Host`, true, map[string]interface{}{"Object": 17})
defer paramResults.Close()
expected := ` In Logging : Debug: 17
`
Expand Down
4 changes: 2 additions & 2 deletions pkg/powershell/powershellobjects.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ func (obj Object) ToString() string {
return makeString(str)
}

// JsonUnmarshal calls the ToString function and unmarshals it into the supplied object
func (obj Object) JsonUnmarshal(userObject interface{}) error {
// JSONUnmarshal calls the ToString function and unmarshals it into the supplied object
func (obj Object) JSONUnmarshal(userObject interface{}) error {
bytes := []byte(obj.ToString())
return json.Unmarshal(bytes, userObject)
}
6 changes: 3 additions & 3 deletions pkg/powershell/runspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ func (context *runspaceContext) recreateRunspace() Runspace {
return Runspace{context}
}

// Runspace corresponds to a powershell runspace.
// Runspace corresponds to a powershell runspace.
//
// Use this object to execute all your powershell commands/scripts, see ExecScript and ExecCommand
//
//
// use .Close() to free
type Runspace struct {
*runspaceContext
Expand All @@ -62,7 +62,7 @@ func CreateRunspaceSimple() Runspace {
// You must call Close when done with this object
func CreateRunspace(loggerCallback logger.Simple, callback CallbackHolder) Runspace {
context := &runspaceContext{log: logger.MakeLoggerFull(loggerCallback),
callback: callback,
callback: callback,
}
context.contextLookup = storeRunspaceContext(context)

Expand Down
10 changes: 5 additions & 5 deletions pkg/powershell/runspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ func ExampleRunspace_ExecCommand_withNamedParameters() {

type printer struct{}

func (_ printer) Write(arg string) {
func (printer) Write(arg string) {
fmt.Print(arg)
}

func ExampleRunspace_ExecCommandJsonMarshalUnknown() {
func ExampleRunspace_ExecCommandJSONMarshalUnknown() {

// create a runspace (where you run your powershell statements in)
runspace := CreateRunspace(printer{}, nil)
Expand All @@ -107,7 +107,7 @@ func ExampleRunspace_ExecCommandJsonMarshalUnknown() {

// write to host the parameters that are passed in
command := `write-host "$args"; foreach($x in $args) {write-host $x};`
results := runspace.ExecScriptJsonMarshalUnknown(command, true, nil, 1, 2, false, "test string", []int{1, 2, 3}, map[string]string{"fruit": "apple", "vegetable": "celery"})
results := runspace.ExecScriptJSONMarshalUnknown(command, true, nil, 1, 2, false, "test string", []int{1, 2, 3}, map[string]string{"fruit": "apple", "vegetable": "celery"})
// auto cleanup the results
defer results.Close()

Expand All @@ -127,7 +127,7 @@ type person struct {
Human bool
}

func ExampleRunspace_ExecScriptJsonMarshalUnknown() {
func ExampleRunspace_ExecScriptJSONMarshalUnknown() {

// create a runspace (where you run your powershell statements in)
runspace := CreateRunspace(printer{}, nil)
Expand All @@ -142,7 +142,7 @@ func ExampleRunspace_ExecScriptJsonMarshalUnknown() {

// Unmarshal into custom object person
var me person
results.Objects[0].JsonUnmarshal(&me)
results.Objects[0].JSONUnmarshal(&me)

fmt.Print("Name: ", me.Name, ", Category: ", me.Category, ", Human: ", me.Human)
// OUTPUT: Name: Knic, Category: 4, Human: true
Expand Down
19 changes: 13 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,39 @@
[![GitHub commits since latest release (branch)](https://img.shields.io/github/commits-since/KnicKnic/go-powershell/latest.svg)](https://github.com/KnicKnic/go-powershell/releases/latest)

# Goal

The goal of this project is to enable you to quickly write golang code and interact with windows via powershell and not use exec. Because powershell is a powerful scripting language you will sometimes want to call back into golang. This is also enabled by this project. Also due to sometimes wanting to host .net and powershell giving you an easy way to wrap .net modules and functions and objects, this project also enables that.

Features:

1. Call from golang to powershell
1. Call from powershell to golang (via special Send-HostCommand commandlet)
1. Easy logging - Trap host output in powershell and call custom logging routines in golang


# Status

It works

1. call scripts / cmdlets
1. reuse variables between calls / invocation
1. Call from golang to powershell
1. Call from powershell back to golang (via special Send-HostCommand commandlet)
1. trap host output in powershell and call custom logging routines in golang
1. has automted tests
1. has automated tests
1. Docs - if you missed the badge above go to https://godoc.org/github.com/KnicKnic/go-powershell/pkg/powershell

This project is not api stable, however I believe it will be simple if you do use the current api to migrate to any future changes.
This project is not api stable, however I believe it will be simple if you do use the current api to migrate to any future changes.

**TODO:**
**TODO:**

- [x] add some code for easy back and forth json serialization of complex objects
- [X] more examples / tests
- [ ] example / helper classes around exception
- [ ] a doc overview
- [x] a doc overview
- [ ] support for default loggers, like glog or log (in seperate package)

# Usage

```go
package main

Expand Down Expand Up @@ -76,9 +80,11 @@ func main() {
```

## Dependencies

This project has a dependency on [native-powershell](https://github.com/KnicKnic/native-powershell). This is a c++/cli project that enables interacting with powershell through a C DLL interface.

### Using native-powershell

1. Simply fetch the dependencies, `go get -d .` and then make sure to build, `go build`
1. Copy the precompiled psh_host.dll into your location so it can be found when running the app
1. cmd - `copy %GOPATH%\src\github.com\KnicKnic\go-powershell\native-powershell\native-powershell-bin\psh_host.dll .`
Expand All @@ -87,12 +93,13 @@ This project has a dependency on [native-powershell](https://github.com/KnicKnic
1. I could not find a better way to go about this and still have things be easy.

### Getting cgo (so you can compile)

Windows - install dependencies - you need gcc. I Use chocolatey to install (easiest way to install gcc)

1. Install chocolatey
1. https://chocolatey.org/docs/installation#installing-chocolatey
1. `choco install mingw -y`


# Docs

https://grokbase.com/t/gg/golang-nuts/154m672a6t/go-nuts-linking-cgo-with-visual-studio-x64-release-libraries-on-windows

0 comments on commit 848c2b7

Please sign in to comment.