Skip to content

Commit 5bb6f82

Browse files
Moved WslFlags functionality and tests to internal package
This avoids circular dependencies between Flags, Configuration, and Configuration-related wslApi.dll calls.
1 parent 8e089ed commit 5bb6f82

File tree

5 files changed

+151
-141
lines changed

5 files changed

+151
-141
lines changed

distro.go

+8-61
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,9 @@ func DefaultDistro(ctx context.Context) (d Distro, err error) {
116116

117117
// Configuration is the configuration of the distro.
118118
type Configuration struct {
119-
Version uint8 // Type of filesystem used (lxfs vs. wslfs, relevant only to WSL1)
120-
DefaultUID uint32 // User ID of default user
121-
InteropEnabled bool // Whether interop with windows is enabled
122-
PathAppended bool // Whether Windows paths are appended
123-
DriveMountingEnabled bool // Whether drive mounting is enabled
124-
undocumentedWSLVersion uint8 // Undocumented variable. WSL1 vs. WSL2.
119+
Version uint8 // Type of filesystem used (lxfs vs. wslfs, relevant only to WSL1)
120+
DefaultUID uint32 // User ID of default user
121+
flags.Unpacked
125122
DefaultEnvironmentVariables map[string]string // Environment variables passed to the distro by default
126123
}
127124

@@ -183,21 +180,21 @@ func (d Distro) GetConfiguration() (c Configuration, err error) {
183180
defer decorate.OnError(&err, "could not access configuration for %s", d.name)
184181

185182
var conf Configuration
186-
var flags flags.WslFlags
183+
var f flags.WslFlags
187184

188185
err = d.backend.WslGetDistributionConfiguration(
189186
d.Name(),
190187
&conf.Version,
191188
&conf.DefaultUID,
192-
&flags,
189+
&f,
193190
&conf.DefaultEnvironmentVariables,
194191
)
195192

196193
if err != nil {
197194
return conf, err
198195
}
196+
conf.Unpacked = flags.Unpack(f)
199197

200-
conf.unpackFlags(flags)
201198
return conf, nil
202199
}
203200

@@ -256,7 +253,7 @@ func (d Distro) configToString() string {
256253
- DriveMountingEnabled: %t
257254
- undocumentedWSLVersion: %d
258255
- DefaultEnvironmentVariables:%s`, c.Version, c.DefaultUID, c.InteropEnabled, c.PathAppended,
259-
c.DriveMountingEnabled, c.undocumentedWSLVersion, fmtEnvs)
256+
c.DriveMountingEnabled, c.UndocumentedWSLVersion, fmtEnvs)
260257
}
261258

262259
// configure is a wrapper around Win32's WslConfigureDistribution.
@@ -266,60 +263,10 @@ func (d Distro) configToString() string {
266263
// - PathAppended
267264
// - DriveMountingEnabled
268265
func (d *Distro) configure(config Configuration) error {
269-
flags, err := config.packFlags()
266+
flags, err := config.Pack()
270267
if err != nil {
271268
return err
272269
}
273270

274271
return d.backend.WslConfigureDistribution(d.Name(), config.DefaultUID, flags)
275272
}
276-
277-
// unpackFlags examines a winWslFlags object and stores its findings in the Configuration.
278-
func (conf *Configuration) unpackFlags(f flags.WslFlags) {
279-
conf.InteropEnabled = false
280-
if flags.ENABLE_INTEROP != 0 {
281-
conf.InteropEnabled = true
282-
}
283-
284-
conf.PathAppended = false
285-
if f&flags.APPEND_NT_PATH != 0 {
286-
conf.PathAppended = true
287-
}
288-
289-
conf.DriveMountingEnabled = false
290-
if f&flags.ENABLE_DRIVE_MOUNTING != 0 {
291-
conf.DriveMountingEnabled = true
292-
}
293-
294-
conf.undocumentedWSLVersion = 1
295-
if f&flags.Undocumented_WSL_VERSION != 0 {
296-
conf.undocumentedWSLVersion = 2
297-
}
298-
}
299-
300-
// packFlags generates a winWslFlags object from the Configuration.
301-
func (conf Configuration) packFlags() (flags.WslFlags, error) {
302-
f := flags.NONE
303-
304-
if conf.InteropEnabled {
305-
f = f | flags.ENABLE_INTEROP
306-
}
307-
308-
if conf.PathAppended {
309-
f = f | flags.APPEND_NT_PATH
310-
}
311-
312-
if conf.DriveMountingEnabled {
313-
f = f | flags.ENABLE_DRIVE_MOUNTING
314-
}
315-
316-
switch conf.undocumentedWSLVersion {
317-
case 1:
318-
case 2:
319-
f = f | flags.Undocumented_WSL_VERSION
320-
default:
321-
return f, fmt.Errorf("unknown WSL version %d", conf.undocumentedWSLVersion)
322-
}
323-
324-
return f, nil
325-
}

internal/flags/flags.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ type WslFlags int32
1212
const (
1313
// All nolints are regarding the use of UPPPER_CASE.
1414

15-
NONE WslFlags = 0x0
16-
ENABLE_INTEROP WslFlags = 0x1 //nolint: revive
17-
APPEND_NT_PATH WslFlags = 0x2 //nolint: revive
18-
ENABLE_DRIVE_MOUNTING WslFlags = 0x4 //nolint: revive
15+
flag_ENABLE_INTEROP WslFlags = 0x1 //nolint:revive
16+
flag_APPEND_NT_PATH WslFlags = 0x2 //nolint:revive
17+
flag_ENABLE_DRIVE_MOUNTING WslFlags = 0x4 //nolint:revive
1918

2019
// Per the conversation at https://github.com/microsoft/WSL-DistroLauncher/issues/96
2120
// the information about version 1 or 2 is on the 4th bit of the flags, which is
2221
// currently referenced neither by the API nor the documentation.
23-
Undocumented_WSL_VERSION WslFlags = 0x8 //nolint: revive
22+
flag_undocumented_WSL_VERSION WslFlags = 0x8 //nolint:revive
2423
)

internal/flags/flags_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package flags_test
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
"github.com/ubuntu/gowsl/internal/flags"
10+
)
11+
12+
func TestUnpackFlags(t *testing.T) {
13+
t.Parallel()
14+
15+
tests := []struct {
16+
wants flags.Unpacked
17+
input flags.WslFlags
18+
}{
19+
{input: flags.WslFlags(0x0), wants: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: false}},
20+
{input: flags.WslFlags(0x1), wants: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: false}},
21+
{input: flags.WslFlags(0x2), wants: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: false}},
22+
{input: flags.WslFlags(0x3), wants: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: false}},
23+
{input: flags.WslFlags(0x4), wants: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: true}},
24+
{input: flags.WslFlags(0x5), wants: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: true}},
25+
{input: flags.WslFlags(0x6), wants: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: true}},
26+
{input: flags.WslFlags(0x7), wants: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: true}},
27+
// The following may be encountered due to an undocumented fourth flagcd
28+
{input: flags.WslFlags(0x8), wants: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: false}},
29+
{input: flags.WslFlags(0x9), wants: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: false}},
30+
{input: flags.WslFlags(0xa), wants: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: false}},
31+
{input: flags.WslFlags(0xb), wants: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: false}},
32+
{input: flags.WslFlags(0xc), wants: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: true}},
33+
{input: flags.WslFlags(0xd), wants: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: true}},
34+
{input: flags.WslFlags(0xe), wants: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: true}},
35+
{input: flags.WslFlags(0xf), wants: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: true}},
36+
}
37+
38+
for _, tc := range tests {
39+
tc := tc
40+
t.Run(fmt.Sprintf("input_0x%x", int(tc.input)), func(t *testing.T) {
41+
t.Parallel()
42+
got := flags.Unpack(tc.input)
43+
assert.Equal(t, tc.wants.InteropEnabled, got.InteropEnabled, "InteropEnabled does not match the expected value")
44+
assert.Equal(t, tc.wants.PathAppended, got.PathAppended, "PathAppended does not match the expected value")
45+
assert.Equal(t, tc.wants.DriveMountingEnabled, got.DriveMountingEnabled, "DriveMountingEnabled does not match the expected value")
46+
})
47+
}
48+
}
49+
50+
func TestPackFlags(t *testing.T) {
51+
t.Parallel()
52+
tests := []struct {
53+
input flags.Unpacked
54+
wants flags.WslFlags
55+
}{
56+
{wants: flags.WslFlags(0x0), input: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: false}},
57+
{wants: flags.WslFlags(0x1), input: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: false}},
58+
{wants: flags.WslFlags(0x2), input: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: false}},
59+
{wants: flags.WslFlags(0x3), input: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: false}},
60+
{wants: flags.WslFlags(0x4), input: flags.Unpacked{InteropEnabled: false, PathAppended: false, DriveMountingEnabled: true}},
61+
{wants: flags.WslFlags(0x5), input: flags.Unpacked{InteropEnabled: true, PathAppended: false, DriveMountingEnabled: true}},
62+
{wants: flags.WslFlags(0x6), input: flags.Unpacked{InteropEnabled: false, PathAppended: true, DriveMountingEnabled: true}},
63+
{wants: flags.WslFlags(0x7), input: flags.Unpacked{InteropEnabled: true, PathAppended: true, DriveMountingEnabled: true}},
64+
}
65+
66+
for _, tc := range tests {
67+
tc := tc
68+
t.Run(fmt.Sprintf("expects_0x%x", int(tc.wants)), func(t *testing.T) {
69+
t.Parallel()
70+
got, _ := tc.input.Pack()
71+
require.Equal(t, tc.wants, got)
72+
})
73+
}
74+
}

internal/flags/packed.go

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package flags
2+
3+
import "fmt"
4+
5+
// Unpacked contains the same information as WslFlags but in a struct instead of an integer.
6+
type Unpacked struct {
7+
InteropEnabled bool // Whether interop with windows is enabled
8+
PathAppended bool // Whether Windows paths are appended
9+
DriveMountingEnabled bool // Whether drive mounting is enabled
10+
UndocumentedWSLVersion uint8 // Undocumented variable. WSL1 vs. WSL2.
11+
}
12+
13+
// Unpack examines a WslFlags object and stores its data in a Unpacked flags struct.
14+
func Unpack(f WslFlags) Unpacked {
15+
var up Unpacked
16+
17+
up.InteropEnabled = false
18+
if f&flag_ENABLE_INTEROP != 0 {
19+
up.InteropEnabled = true
20+
}
21+
22+
up.PathAppended = false
23+
if f&flag_APPEND_NT_PATH != 0 {
24+
up.PathAppended = true
25+
}
26+
27+
up.DriveMountingEnabled = false
28+
if f&flag_ENABLE_DRIVE_MOUNTING != 0 {
29+
up.DriveMountingEnabled = true
30+
}
31+
32+
up.UndocumentedWSLVersion = 1
33+
if f&flag_undocumented_WSL_VERSION != 0 {
34+
up.UndocumentedWSLVersion = 2
35+
}
36+
37+
return up
38+
}
39+
40+
// Pack generates a WslFlags object from the Unpacked struct.
41+
func (conf Unpacked) Pack() (WslFlags, error) {
42+
var f WslFlags
43+
44+
if conf.InteropEnabled {
45+
f = f | flag_ENABLE_INTEROP
46+
}
47+
48+
if conf.PathAppended {
49+
f = f | flag_APPEND_NT_PATH
50+
}
51+
52+
if conf.DriveMountingEnabled {
53+
f = f | flag_ENABLE_DRIVE_MOUNTING
54+
}
55+
56+
switch conf.UndocumentedWSLVersion {
57+
case 1:
58+
case 2:
59+
f = f | flag_undocumented_WSL_VERSION
60+
default:
61+
return f, fmt.Errorf("unknown WSL version %d", conf.UndocumentedWSLVersion)
62+
}
63+
64+
return f, nil
65+
}

internal_test.go

-75
This file was deleted.

0 commit comments

Comments
 (0)