Change project layout to make easier debug / tests"

This commit is contained in:
eleksir
2024-09-22 23:52:57 +03:00
parent 9d3bc186cc
commit 4bff21f4c7
112 changed files with 271 additions and 1683 deletions

View File

@@ -1,8 +1,3 @@
Note that this project is largely unmaintained as I don't have the time to do
or support more development. Please consider using this fork instead:
https://github.com/jezek/xgb
XGB is the X Go Binding, which is a low-level API to communicate with the
core X protocol and many of the X extensions. It is closely modeled after
XCB and xpyb.
@@ -25,7 +20,7 @@ BurntSushi's Fork
I've forked the XGB repository from Google Code due to inactivty upstream.
Godoc documentation can be found here:
https://godoc.org/github.com/BurntSushi/xgb
http://godoc.burntsushi.net/pkg/github.com/BurntSushi/xgb/
Much of the code has been rewritten in an effort to support thread safety
and multiple extensions. Namely, go_client.py has been thrown away in favor

View File

@@ -168,14 +168,13 @@ func (c *Conn) dial(display string) error {
// Connect to server
if len(socket) != 0 {
c.conn, err = net.Dial("unix", socket+":"+c.display)
} else if len(c.host) != 0 && c.host != "unix" {
} else if len(c.host) != 0 {
if protocol == "" {
protocol = "tcp"
}
c.conn, err = net.Dial(protocol,
c.host+":"+strconv.Itoa(6000+c.DisplayNumber))
} else {
c.host = ""
c.conn, err = net.Dial("unix", "/tmp/.X11-unix/X"+c.display)
}

View File

@@ -1,18 +1,18 @@
xgbutil is a utility library designed to work with the X Go Binding. This
project's main goal is to make various X related tasks easier. For example,
binding keys, using the EWMH or ICCCM specs with the window manager,
xgbutil is a utility library designed to work with the X Go Binding. This
project's main goal is to make various X related tasks easier. For example,
binding keys, using the EWMH or ICCCM specs with the window manager,
moving/resizing windows, assigning function callbacks to particular events,
drawing images to a window, etc.
xgbutil attempts to be thread safe, but it has not been completely tested in
this regard. In general, the X event loop implemented in the xevent package is
sequential. The idea is to be sequential by default, and let the user spawn
concurrent code at their discretion. (i.e., the complexity of making the main
xgbutil attempts to be thread safe, but it has not been completely tested in
this regard. In general, the X event loop implemented in the xevent package is
sequential. The idea is to be sequential by default, and let the user spawn
concurrent code at their discretion. (i.e., the complexity of making the main
event loop generally concurrent is vast.)
You may sleep safely at night by assuming that XGB is thread safe, though.
To start using xgbutil, you should have at least a passing familiarity with X.
To start using xgbutil, you should have at least a passing familiarity with X.
Your first stop should be the examples directory.
Installation
@@ -31,24 +31,29 @@ Quick Example
go get github.com/BurntSushi/xgbutil/_examples/window-name-sizes
"$GOPATH"/bin/window-name-sizes
The output will be a list of names of all top-level windows and their geometry
including window manager decorations. (Assuming your window manager supports
The output will be a list of names of all top-level windows and their geometry
including window manager decorations. (Assuming your window manager supports
some basic EWMH properties.)
Documentation
=============
https://godoc.org/github.com/BurntSushi/xgbutil
gopkgdoc is well-suited to provide documentation for xgbutil. Its cross-package
hyperlinking on types is also extremely useful, since much of xgbutil relies on
XGB.
With that said, documentation is also hosted here:
http://godoc.burntsushi.net/pkg/github.com/BurntSushi/xgbutil/
Examples
========
There are several examples in the examples directory covering common use cases.
There are several examples in the examples directory covering common use cases.
They are heavily documented and should run out of the box.
Python
======
An older project of mine, xpybutil, served as inspiration for xgbutil. If you
want to use Python, xpybutil should help quite a bit. Please note though, that
at this point, xgbutil provides a lot more functionality and is much better
An older project of mine, xpybutil, served as inspiration for xgbutil. If you
want to use Python, xpybutil should help quite a bit. Please note though, that
at this point, xgbutil provides a lot more functionality and is much better
documented.
xpybutil project URL: https://github.com/BurntSushi/xpybutil

View File

@@ -4,6 +4,7 @@ import "fmt"
// Public error definitions
var (
ErrCronJobInvalid = fmt.Errorf("gocron: CronJob: invalid crontab")
ErrCronJobParse = fmt.Errorf("gocron: CronJob: crontab parse failure")
ErrDailyJobAtTimeNil = fmt.Errorf("gocron: DailyJob: atTime within atTimes must not be nil")
ErrDailyJobAtTimesNil = fmt.Errorf("gocron: DailyJob: atTimes must not be nil")

View File

@@ -196,7 +196,7 @@ func (e *executor) start() {
default:
// runner is busy, reschedule the work for later
// which means we just skip it here and do nothing
// TODO when metrics are added, this should increment a rescheduled metric
e.incrementJobCounter(*j, SingletonRescheduled)
e.sendOutForRescheduling(&jIn)
}
} else {
@@ -397,9 +397,7 @@ func (e *executor) runJob(j internalJob, jIn jobIn) {
startTime := time.Now()
err := e.callJobWithRecover(j)
if e.monitor != nil {
e.monitor.RecordJobTiming(startTime, time.Now(), j.id, j.name, j.tags)
}
e.recordJobTiming(startTime, time.Now(), j)
if err != nil {
_ = callJobFuncWithParams(j.afterJobRunsWithError, j.id, j.name, err)
e.incrementJobCounter(j, Fail)
@@ -422,6 +420,12 @@ func (e *executor) callJobWithRecover(j internalJob) (err error) {
return callJobFuncWithParams(j.function, j.parameters...)
}
func (e *executor) recordJobTiming(start time.Time, end time.Time, j internalJob) {
if e.monitor != nil {
e.monitor.RecordJobTiming(start, end, j.id, j.name, j.tags)
}
}
func (e *executor) incrementJobCounter(j internalJob, status JobStatus) {
if e.monitor != nil {
e.monitor.IncrementJob(j.id, j.name, j.tags, status)

View File

@@ -116,7 +116,7 @@ type cronJobDefinition struct {
withSeconds bool
}
func (c cronJobDefinition) setup(j *internalJob, location *time.Location, _ time.Time) error {
func (c cronJobDefinition) setup(j *internalJob, location *time.Location, now time.Time) error {
var withLocation string
if strings.HasPrefix(c.crontab, "TZ=") || strings.HasPrefix(c.crontab, "CRON_TZ=") {
withLocation = c.crontab
@@ -140,6 +140,9 @@ func (c cronJobDefinition) setup(j *internalJob, location *time.Location, _ time
if err != nil {
return errors.Join(ErrCronJobParse, err)
}
if cronSchedule.Next(now).IsZero() {
return ErrCronJobInvalid
}
j.jobSchedule = &cronJob{cronSchedule: cronSchedule}
return nil
@@ -456,6 +459,8 @@ type oneTimeJobDefinition struct {
func (o oneTimeJobDefinition) setup(j *internalJob, _ *time.Location, now time.Time) error {
sortedTimes := o.startAt(j)
slices.SortStableFunc(sortedTimes, ascendingTime)
// deduplicate the times
sortedTimes = removeSliceDuplicatesTimeOnSortedSlice(sortedTimes)
// keep only schedules that are in the future
idx, found := slices.BinarySearchFunc(sortedTimes, now, ascendingTime)
if found {
@@ -469,6 +474,16 @@ func (o oneTimeJobDefinition) setup(j *internalJob, _ *time.Location, now time.T
return nil
}
func removeSliceDuplicatesTimeOnSortedSlice(times []time.Time) []time.Time {
ret := make([]time.Time, 0, len(times))
for i, t := range times {
if i == 0 || t != times[i-1] {
ret = append(ret, t)
}
}
return ret
}
// OneTimeJobStartAtOption defines when the one time job is run
type OneTimeJobStartAtOption func(*internalJob) []time.Time

View File

@@ -11,9 +11,10 @@ type JobStatus string
// The different statuses of job that can be used.
const (
Fail JobStatus = "fail"
Success JobStatus = "success"
Skip JobStatus = "skip"
Fail JobStatus = "fail"
Success JobStatus = "success"
Skip JobStatus = "skip"
SingletonRescheduled JobStatus = "singleton_rescheduled"
)
// Monitor represents the interface to collect jobs metrics.

View File

@@ -311,7 +311,7 @@ func (s *scheduler) selectRemoveJob(id uuid.UUID) {
}
// Jobs coming back from the executor to the scheduler that
// need to evaluated for rescheduling.
// need to be evaluated for rescheduling.
func (s *scheduler) selectExecJobsOutForRescheduling(id uuid.UUID) {
select {
case <-s.shutdownCtx.Done():
@@ -359,6 +359,13 @@ func (s *scheduler) selectExecJobsOutForRescheduling(id uuid.UUID) {
next = j.next(next)
}
}
// Clean up any existing timer to prevent leaks
if j.timer != nil {
j.timer.Stop()
j.timer = nil // Ensure timer is cleared for GC
}
j.nextScheduled = append(j.nextScheduled, next)
j.timer = s.exec.clock.AfterFunc(next.Sub(s.now()), func() {
// set the actual timer on the job here and listen for

View File

@@ -1,13 +0,0 @@
# Security Policy
## Supported Versions
Security updates are applied only to the latest release.
## Reporting a Vulnerability
If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
Please disclose it at [security advisory](https://github.com/go-ole/go-ole/security/advisories/new).
This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.

View File

@@ -6,29 +6,7 @@
version: "1.3.0.{build}-alpha-{branch}"
os: Visual Studio 2019
build: off
skip_tags: true
clone_folder: c:\gopath\src\github.com\go-ole\go-ole
environment:
GOPATH: c:\gopath
GOROOT: c:\go
DOWNLOADPLATFORM: "x64"
before_test:
# - Download COM Server
- ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip"
- 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL
- c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat
test_script:
- go test -v -cover ./...
# go vet has false positives on unsafe.Pointer with windows/sys. Disabling since it is recommended to use go test instead.
# - go vet ./...
os: Windows Server 2012 R2
branches:
only:
@@ -37,19 +15,26 @@ branches:
- v1.1
- v1.0
matrix:
allow_failures:
- environment:
GOROOT: C:\go-x86
DOWNLOADPLATFORM: "x86"
- environment:
GOROOT: C:\go118
DOWNLOADPLATFORM: "x64"
- environment:
GOROOT: C:\go118-x86
DOWNLOADPLATFORM: "x86"
skip_tags: true
clone_folder: c:\gopath\src\github.com\go-ole\go-ole
environment:
GOPATH: c:\gopath
matrix:
- GOARCH: amd64
GOVERSION: 1.5
GOROOT: c:\go
DOWNLOADPLATFORM: "x64"
install:
- choco install mingw
- SET PATH=c:\tools\mingw64\bin;%PATH%
# - Download COM Server
- ps: Start-FileDownload "https://github.com/go-ole/test-com-server/releases/download/v1.0.2/test-com-server-${env:DOWNLOADPLATFORM}.zip"
- 7z e test-com-server-%DOWNLOADPLATFORM%.zip -oc:\gopath\src\github.com\go-ole\go-ole > NUL
- c:\gopath\src\github.com\go-ole\go-ole\build\register-assembly.bat
# - set
- go version
- go env
- go get -u golang.org/x/tools/cmd/cover
@@ -60,9 +45,10 @@ build_script:
- cd c:\gopath\src\github.com\go-ole\go-ole
- go get -v -t ./...
- go build
- go test -v -cover ./...
# disable automatic tests
test: on
test: off
# disable deployment
deploy: off

View File

@@ -11,7 +11,6 @@ import (
var (
procCoInitialize = modole32.NewProc("CoInitialize")
procCoInitializeEx = modole32.NewProc("CoInitializeEx")
procCoInitializeSecurity = modole32.NewProc("CoInitializeSecurity")
procCoUninitialize = modole32.NewProc("CoUninitialize")
procCoCreateInstance = modole32.NewProc("CoCreateInstance")
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
@@ -38,9 +37,6 @@ var (
procDispatchMessageW = moduser32.NewProc("DispatchMessageW")
)
// This is to enable calling COM Security initialization multiple times
var bSecurityInit bool = false
// coInitialize initializes COM library on current thread.
//
// MSDN documentation suggests that this function should not be called. Call
@@ -72,35 +68,6 @@ func coInitializeEx(coinit uint32) (err error) {
return
}
// coInitializeSecurity: Registers security and sets the default security values
// for the process.
func coInitializeSecurity(cAuthSvc int32,
dwAuthnLevel uint32,
dwImpLevel uint32,
dwCapabilities uint32) (err error) {
// Check COM Security initialization has done previously
if !bSecurityInit {
// https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializesecurity
hr, _, _ := procCoInitializeSecurity.Call(
uintptr(0), // Allow *all* VSS writers to communicate back!
uintptr(cAuthSvc), // Default COM authentication service
uintptr(0), // Default COM authorization service
uintptr(0), // Reserved parameter
uintptr(dwAuthnLevel), // Strongest COM authentication level
uintptr(dwImpLevel), // Minimal impersonation abilities
uintptr(0), // Default COM authentication settings
uintptr(dwCapabilities), // Cloaking
uintptr(0)) // eserved parameter
if hr != 0 {
err = NewError(hr)
} else {
// COM Security initialization done make global flag true.
bSecurityInit = true
}
}
return
}
// CoInitialize initializes COM library on current thread.
//
// MSDN documentation suggests that this function should not be called. Call
@@ -129,15 +96,6 @@ func CoUninitialize() {
procCoUninitialize.Call()
}
// CoInitializeSecurity: Registers security and sets the default security values
// for the process.
func CoInitializeSecurity(cAuthSvc int32,
dwAuthnLevel uint32,
dwImpLevel uint32,
dwCapabilities uint32) (err error) {
return coInitializeSecurity(cAuthSvc, dwAuthnLevel, dwImpLevel, dwCapabilities)
}
// CoTaskMemFree frees memory pointer.
func CoTaskMemFree(memptr uintptr) {
procCoTaskMemFree.Call(memptr)

View File

@@ -1,4 +1,3 @@
//go:build windows
// +build windows
package ole
@@ -93,7 +92,7 @@ func invoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}
case int8:
vargs[n] = NewVariant(VT_I1, int64(v.(int8)))
case *int8:
vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*int8)))))
vargs[n] = NewVariant(VT_I1|VT_BYREF, int64(uintptr(unsafe.Pointer(v.(*uint8)))))
case int16:
vargs[n] = NewVariant(VT_I2, int64(v.(int16)))
case *int16:

View File

@@ -99,7 +99,7 @@ func (v *VARIANT) Value() interface{} {
case VT_DISPATCH:
return v.ToIDispatch()
case VT_BOOL:
return (v.Val & 0xffff) != 0
return v.Val != 0
}
return nil
}