Skip to content
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2a5230b
[storage-file-share] updated samples
witemple-msft Dec 9, 2019
dd98eb2
[prep-samples] allow files that don't have a matching import and just…
witemple-msft Dec 10, 2019
2fe35d9
[storage-file-share] typescript samples in shape
witemple-msft Dec 10, 2019
0d68724
[storage-file-share] made clean samples step clean up package locks i…
witemple-msft Dec 10, 2019
72e49cb
[prep-samples] added support for javascript samples
witemple-msft Dec 10, 2019
adb764c
[storage-file-share] Added dotenv and updated instructions
witemple-msft Dec 10, 2019
160ab84
[storage-file-share] Brought js samples in line with ts samples
witemple-msft Dec 10, 2019
8d1070d
[storage-file-share] bugfixes to ts samples packages
witemple-msft Dec 10, 2019
7951b5a
[storage-file-share] NPM scripts to run samples
witemple-msft Dec 10, 2019
03c7b22
[storage-file-share] remove execute-samples.js and use new runners
witemple-msft Dec 10, 2019
6adcb5d
[storage-file-share] added missing sample.env to js samples
witemple-msft Dec 11, 2019
9a793e6
[storage-file-share] Fixed sample package names
witemple-msft Dec 11, 2019
ef9a3d4
[storage-blob] update samples to be like storage-file-share
witemple-msft Dec 11, 2019
6ac61c7
[samples] Moved run-samples to common/scripts
witemple-msft Dec 11, 2019
12b3d00
[storage-file-share] Changed proxyAuth samples to exit if proxy infor…
witemple-msft Dec 11, 2019
5465f4c
[storage-file-share] changed iterators-handles to exit if share/direc…
witemple-msft Dec 11, 2019
8039b80
[run-samples] Error handling
witemple-msft Dec 11, 2019
e552211
[storage-file-share] Fixed sample errors due to prep-samples tree con…
witemple-msft Dec 11, 2019
b77c6b4
[storage-file-share] Changed from exceptions to a simple return in ca…
witemple-msft Dec 11, 2019
14e6fbe
[run-samples] Fixed an ignore bug
witemple-msft Dec 11, 2019
d2e70ca
[storage-file-share] Removed scripts and references to execute:all
witemple-msft Dec 11, 2019
1ab154b
[prep-samples] typo
witemple-msft Dec 11, 2019
b27c65c
[storage-file-share] Update sample.env
witemple-msft Dec 11, 2019
0a1edcf
[storage-blob] Replicate updates for storage-blob
witemple-msft Dec 11, 2019
8f8b6e2
[storage-blob] remove execute-samples.js
witemple-msft Dec 11, 2019
2de6076
[storage-blob] Fixed a bug in blob samples ts readme
witemple-msft Dec 12, 2019
5de8348
[storage-queue] Replicate updates to samples on storage-queue
witemple-msft Dec 12, 2019
30b38b4
[run-samples] made the runner give a brief digest of errors
witemple-msft Dec 12, 2019
46ac984
[storage] Made aad auth samples skippable when AAD information is not…
witemple-msft Dec 12, 2019
77c602d
[storage] changed proxyAuth samples to use HTTP[s]_PROXY vars
witemple-msft Dec 12, 2019
c1fd600
[storage-file-share] Fixed a bug in iterators sample when no queues e…
witemple-msft Dec 12, 2019
6f97268
[scripts] Make the scripts less wordy and fixed a bug in run-samples
witemple-msft Dec 12, 2019
98fa55c
[storage] Updated sample.env files to use HTTP_PROXY
witemple-msft Dec 12, 2019
787e631
[storage] Fixed wrong keywords in three sample packages.
witemple-msft Dec 16, 2019
1e25ece
[prep-samples] tsDir -> dir
witemple-msft Dec 16, 2019
d6653e5
[storage-queue] Removed need for sampleHelpers
witemple-msft Dec 16, 2019
e10e99b
[storage-file-share] Remove sampleHelpers
witemple-msft Dec 16, 2019
3145d3c
[storage-blob] removed sampleHelpers
witemple-msft Dec 16, 2019
3be4483
[run-samples] Removed outdated sampleHelpers.js from ignore list
witemple-msft Dec 16, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 44 additions & 22 deletions common/scripts/prep-samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ const fs =
return {
readdir: promisify(baseFS.readdir),
readFile: promisify(baseFS.readFile),
stat: promisify(baseFS.stat),
writeFile: promisify(baseFS.writeFile)
};
})();

/**
* Breadth-first search for files ending in .ts, starting from `tsDir`
* Breadth-first search for files matching a given predicate
*
* @param {string} tsDir The root of the sample tree to search

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: tsDir => dir

* @param {(fs.Entry) => boolean} matches Predicate that decides whether or not a file entry is included
* @returns
*/
async function* findAllTsFiles(tsDir) {
async function* findMatchingFiles(tsDir, matches) {
const initialFiles = await fs.readdir(tsDir, { withFileTypes: true });

// BFS Queue and queue index
Expand All @@ -61,11 +61,7 @@ async function* findAllTsFiles(tsDir) {
for (const child of children) {
q.push([child, fullPath]);
}
} else if (
entry.isFile() &&
entry.name.endsWith(".ts") &&
!entry.name.endsWith(".d.ts")
) {
} else if (matches(entry)) {
yield fullPath;
} else if (
entry.isBlockDevice() ||
Expand All @@ -87,21 +83,26 @@ async function* findAllTsFiles(tsDir) {
}

/**
* Replaces package imports with relative imports for CI
* Replaces package require/import statements with relative paths for CI
*
* @param {string} file the name of the file to open and process
* @param {string} baseDir The base directory of the package
* @param {string} fileName the name of the file to open and process
* @param {string} baseDir the base directory of the package
* @param {string} pkgName name of the package to use when looking for package-local imports
*/
async function enableLocalRun(fileName, baseDir, pkgName) {
const fileContents = await fs.readFile(fileName, { encoding: "utf-8" });
const importRegex = new RegExp(
`import\\s+(.*)\\s+from\\s+"${pkgName}";?\\s?`,
"s"
);
const isTs = fileName.endsWith(".ts");
const importRegex = isTs
? new RegExp(`import\\s+(.*)\\s+from\\s+"${pkgName}";?\\s?`, "s")
Comment thread
richardpark-msft marked this conversation as resolved.
: new RegExp(`const\\s+(.*)\\s*=\\s*require\\("${pkgName}"\\);?\\s?`, "s");

if (!importRegex.exec(fileContents)) {
throw new Error(`Sample ${fileName} did not contain an import statement!`);
// With the newer methods of using helper files and batch running, this
// should be a warning
console.warn(
`[prep-samples] skipping ${fileName} because it did not contain a matching import/require`
);
return;
}

const relativeDir = path.dirname(fileName.replace(baseDir, ""));
Expand All @@ -112,12 +113,21 @@ async function enableLocalRun(fileName, baseDir, pkgName) {
const depth =
relativeDir.length - relativeDir.split(path.sep).join("").length;

const relativeImportPath = new Array(depth).fill("..").join("/") + "/src";
let relativePath = new Array(depth).fill("..").join("/");
Comment thread
jeremymeng marked this conversation as resolved.

if (isTs) {
// TypeScript imports should use src directly
relativePath += "/src";
}

const updatedContents = fileContents.replace(
importRegex,
`import $1 from "${relativeImportPath}";`
isTs
? `import $1 from "${relativePath}";`
: `const $1 = require("${relativePath}");`
);

console.log("[prep-samples] Updating imports in", fileName);
return fs.writeFile(fileName, updatedContents, { encoding: "utf-8" });
}

Expand All @@ -132,16 +142,28 @@ async function main() {
baseDir = process.cwd();
}

const tsDir = path.join(baseDir, "samples", "typescript");
const package = require(path.join(baseDir, "package.json"));

console.log(
"[prep-samples] Preparing samples for package:",
`${package.name}@${package.version}`
);

for await (const fileName of findAllTsFiles(tsDir)) {
console.log("[prep-samples] Updating imports in", fileName);
const tsDir = path.join(baseDir, "samples", "typescript", "src");
for await (const fileName of findMatchingFiles(
tsDir,
entry =>
entry.isFile() &&
entry.name.endsWith(".ts") &&
!entry.name.endsWith(".d.ts")
)) {
await enableLocalRun(fileName, baseDir, package.name);
}

const jsDir = path.join(baseDir, "samples", "javascript");
for await (const fileName of findMatchingFiles(
jsDir,
entry => entry.isFile() && entry.name.endsWith(".js")
)) {
await enableLocalRun(fileName, baseDir, package.name);
}
}
Expand Down
115 changes: 115 additions & 0 deletions common/scripts/run-samples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* run-samples.js
*
* Runs all JavaScript files in a directory, using the calling convention for
* our sample code.
*/

const baseFS = require("fs");
const path = require("path");

const IGNORE = ["node_modules", "sampleHelpers.js"];

// Node >= 10 provide fs.promises, but since we're still building Node 8 for now
// we need to use util.promisify if fs.promises doesn't exist
const fs =
baseFS.promises ||
(() => {
const promisify = require("util").promisify;
return {
readdir: promisify(baseFS.readdir)
};
})();

/**
* Breadth-first search for files matching a given predicate
*
* @param {string} tsDir The root of the sample tree to search
* @param {(fs.Entry) => boolean} matches Predicate that decides whether or not a file entry is included
* @returns
*/
async function* findMatchingFiles(tsDir, matches) {
const initialFiles = await fs.readdir(tsDir, { withFileTypes: true });

// BFS Queue and queue index
const q = initialFiles.map(f => [f, tsDir]);

while (q.length) {
// [fs.Dirent, string] (file and dirName part of the full path)
const [entry, dirName] = q.shift();
const fullPath = path.join(dirName, entry.name);

if (IGNORE.includes(entry.name)) {
console.log("[run-samples] Ignoring", fullPath);
continue;
}

if (entry.isDirectory()) {
// Enqueue children of this directory to the bfs
const children = await fs.readdir(fullPath, { withFileTypes: true });
for (const child of children) {
q.push([child, fullPath]);
}
} else if (matches(entry)) {
yield fullPath;
}
}

// The full trace of files visited by the iterator is returned and can be accessed using `iter.value`
// once it is `done`, in case it is ever needed for debugging
return q;
}

async function main() {
// Accept a base directory
const args = process.argv.slice(2);

let sampleDir;
if (args.length) {
sampleDir = path.resolve(args[0]);
} else {
sampleDir = process.cwd();
}

// Patch the environment for the sample helper
process.env.BATCH_RUN_SAMPLES = "true";

console.log("[run-samples] Running all samples in:", sampleDir);

let errors = [];

for await (const fileName of findMatchingFiles(
sampleDir,
entry => entry.isFile() && entry.name.endsWith(".js")
)) {
console.log("[run-samples] Running", fileName);
const { main: sampleMain } = require(fileName);
try {
await sampleMain();
} catch (err) {
const truncatedError = err
.toString()
.split("\n")[0]
.slice(0, 100);
errors.push([path.basename(fileName), truncatedError]);
console.warn("[run-samples] Error in", fileName, ":", err);
console.warn("[run-samples] Continuing ...");
}
}

if (errors.length > 0) {
console.error("[run-samples] Errors occurred in the following files:");
for (const [fileName, error] of errors) {
console.error(" -", fileName, "(", error, ")");
}
process.exit(1);
}
}

main().catch(err => {
console.error("[run-samples] Error:", err);
process.exit(1);
});
80 changes: 0 additions & 80 deletions sdk/storage/storage-blob/execute-samples.js

This file was deleted.

9 changes: 6 additions & 3 deletions sdk/storage/storage-blob/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@
"build:autorest": "autorest ./swagger/README.md --typescript --package-version=12.0.1 --use=@microsoft.azure/autorest.typescript@5.0.1",
"build:es6": "tsc -p tsconfig.json",
"build:nodebrowser": "rollup -c 2>&1",
"build:js-samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1",
"build:ts-samples": "npm run clean && cd samples && tsc -p . ",
"build:samples": "npm run clean && npm run build:es6 && cross-env ONLY_NODE=true rollup -c 2>&1 && npm run build:prep-samples",
"build:prep-samples": "node ../../../common/scripts/prep-samples.js && cd samples && tsc",
"build:test": "npm run build:es6 && rollup -c rollup.test.config.js 2>&1",
"build": "npm run build:es6 && npm run build:nodebrowser && api-extractor run --local",
"check-format": "prettier --list-different --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"clean": "rimraf dist dist-esm dist-test typings temp browser/*.js* browser/*.zip statistics.html coverage coverage-browser .nyc_output *.tgz *.log test*.xml TEST*.xml",
"clean:samples": "rimraf samples/javascript/node_modules samples/typescript/node_modules samples/typescript/dist samples/typescript/package-lock.json samples/javascript/package-lock.json",
"extract-api": "tsc -p . && api-extractor run --local",
"execute:samples": "node execute-samples.js",
"execute:js-samples": "node ../../../common/scripts/run-samples.js samples/javascript/",
"execute:ts-samples": "node ../../../common/scripts/run-samples.js samples/typescript/dist/samples/typescript/src/",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT]
samples/typescript/dist/samples/typescript/src/ ?
samples/typescript/dist/ is not enough?

@willmtemple Will Temple (willmtemple) Dec 16, 2019

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because it is not using the rollup artifact. It is actually importing the package sources as modules, so the tree in samples/typescript/dist after compilation looks something like this:

dist/
  - samples/
    - typescript/
      - src/
        - basic.js
        - ... (compiled sample code)
  - src/
    - StorageClient.js
    - ... (compiled client code)

An alternative would be to use ts-node rather than compile and run the samples, like the previous script was doing, but that has its own set of problems (would need to make the *-samples scripts their own package and add ts-node as a dependency, otherwise we would be requiring global ts-node -- more than I think I can get done before leaving for the holidays).

"execute:samples": "npm run build:samples && npm run execute:js-samples && npm run execute:ts-samples",
"format": "prettier --write --config ../../.prettierrc.json \"src/**/*.ts\" \"test/**/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "karma start --single-run",
"integration-test:node": "nyc mocha --require source-map-support/register --reporter mocha-multi --reporter-options spec=-,mocha-junit-reporter=- --full-trace -t 120000 --retries 2 dist-test/index.node.js",
Expand Down
Loading